2. [Compito]: Il problema
Parole chiave: algoritmi, nozioni di base su Java: array, I/O, cicli, test, gestione delle eccezioni
Lettura consigliata: Capitolo 1 di [rif1]: Le basi del linguaggio Java
2.1. Supporto
La cartella [support / chap-02] contiene l'algoritmo da implementare in C# e Java.
2.2. Il problema da risolvere
Vogliamo scrivere un programma che, la notte delle elezioni, possa calcolare il numero di seggi conquistati dalle varie liste di candidati. Più avanti, troveremo il metodo per calcolare i seggi per un'elezione a rappresentanza proporzionale utilizzando la media più alta, come spiegato in un articolo del quotidiano Ouest-France del 15 marzo 1986.
Scriveremo un'applicazione Java "da console", ovvero un'applicazione che utilizza la tastiera e lo schermo per interagire con l'utente. Chiederà all'utente le seguenti informazioni (inserite tramite la tastiera):
- numero di seggi da assegnare
- numero di liste in competizione
- per ogni lista: il nome e il numero di voti
Utilizzando queste informazioni, l'applicazione calcola il numero di seggi ottenuti da ciascuna lista e li visualizza sullo schermo nel seguente formato:
dove [Xi] è il nome della lista n. i e [Ni] è il numero di seggi che ha ottenuto.
L'articolo di Ouest-France del 15 marzo 1986:


2.3. La soluzione algoritmica
Una soluzione algoritmica potrebbe essere la seguente:
| début-programme
// données
saisieOK : booléen
nbSiègesAPourvoir : entier
nbListes : entier
nomListe[] : chaînes de caractères
voixListe[] : entier
elimineListe[] : booléen
siegesListe[] : entier
moyenneListe[] : réel
i : entier
nbVoixUtiles : entier
quotientElectoral : réel
nbSiègesPourvus : entier
moyenneMax : réel
Max : entier iSiège : entier
// code
// nbre de sièges à pourvoir
saisieOK<-faux
tant que non saisieOK
écrire "Nombre de sièges à pourvoir : "
lire nbSiègesAPourvoir
si nbSiègesAPourvoir n'is not an integer >0 then
écrire "Erreur : tapez un nombre entier >0"
sinon
saisieOK<-vrai
finsi
fintantque
// nbre de listes en compétition
saisieOK<-faux
tant que non saisieOK
écrire "Nombre de listes en compétition : "
lire nbListes
si nbListes n'is not an integer >0 then
écrire "Erreur : tapez un nombre entier >0"
sinon
saisieOK<-vrai
finsi
fintantque
// dimensionnement des tableaux
dimensionner les tableau nomListe, voixListe, elimineListe, siegesListe, moyenneListe à nbListes éléments
// saisie des noms et voix des listes
totalVoix<-0
pour i variant de 0 à nbListes-1
// saisie du nom de la liste i
saisieOK<-faux
tantque non saisieOK
écrire "Nom de la liste n° ", i, " : "
lire nomListe[i]
si nomListe[i] est vide alors
écrire "Erreur : Tapez un nom non vide"
sinon
saisieOK<-vrai
finsi
fintantque
// saisie du nombre de voix de la liste i
saisieOK<-faux
tantque non saisieOK
écrire "Nombre de voix de la liste ", nomListe[i] , " : "
lire voixListe[i]
si voixListe[i] n'is not an integer >=0 then
écrire "Erreur : tapez un nombre entier >=0"
sinon
saisieOK<-vrai
finsi
fintantque
// on incrémente le total des voix
totalVoix<- totalVoix+voixListe[i]79.finpour 80.
// calcul des voix utiles
nbVoixUtiles<-0
pour i variant de 0 à nbListes-1
si (voixListe[i]/totalVoix)<0.05 alors
elimineListe[i]<-vrai
sinon
elimineListe[i]<-faux
nbVoixUtiles<-nbVoixUtiles+voixListe[i]
finsi
finpour
// y-a-t-il des listes non éliminées ?
si nbVoixUtiles=0 alors
écrire "Erreur : toutes les listes ont été éliminées"
arrêt du programme
finsi
// répartition des sièges au quotient
quotientElectoral <- nbVoixUtiles / nbSiègesAPourvoir
nbSiègesPourvus<- 0
pour i variant de 0 à nbListes-1
si non elimineListe[i] alors
siegesListe[i]<- partie entière de (voixListe[i]/quotientElectoral)
moyenneListe[i] <- voixListe[i] / (siegesListe[i]+1)
nbSiègesPourvus<-nbSiègesPourvus+siegesListe[i]
sinon
siegesListe[i]<-0
finsi
finpour
// répartition des sièges restants à la plus forte moyenne
// 1 siège est attribué à chaque tour de boucle
pour iSiège variant de 0 à nbSiègesAPourvoir - nbSiègesPourvus - 1
// recherche de la liste ayant la + forte moyenne
moyenneMax<- (-1)
pour i variant de 0 à nbListes-1
si non elimineListe[i] alors
si moyenneListe[i] > moyenneMax alors
moyenneMax <- moyenneListe[i]
iMax <- i
finsi
finsi
finpour
// on attribue 1 siège à la liste de + forte moyenne
siegeListe[iMax] <- siegeListe[iMax]+1
// et on change sa moyenne
moyenneListe[iMax] <- voixListe[iMax]/(siegeListe[iMax]+1)
finpour
// affichage résultats sans tri
pour i variant de 0 à nbListes-1
si elimineListe[i] alors
écrire "La liste ", nomListe[i], " a été éliminée"
sinon
écrire "La liste ", nomListe[i], " a obtenu ",
siegesListe[i], " siège(s)"
finsi
finpour
fin-programme
|
2.4. Lavoro da svolgere
Q1: Tradurre l'algoritmo in C#. Implementarlo utilizzando Visual Studio.
Q2: Tradurre l'algoritmo in Java, traendo ispirazione dal codice C#. Implementare il programma Java in un ambiente Eclipse simile al seguente:
- [1]: Il progetto si chiama [elections-01]
- [2]: L'applicazione verrà inserita in un pacchetto, in questo caso [istia.st.elections]
- [3]: [MainElections.java] è il codice sorgente dell'applicazione scritta nella sezione precedente
- [4]: la classe [MainElections] viene eseguita
Un esempio di esecuzione potrebbe essere il seguente:
