2. [TD]: Het probleem
Trefwoorden: algoritmiek, basisbeginselen van Java: arrays, I/O, lussen, tests, uitzonderingsafhandeling
Aanbevolen lectuur: hoofdstuk 1 van [ref1]: De basis van de Java-taal
2.1. Support
De map [support / chap-02] bevat het algoritme dat in C# en Java moet worden vertaald.
2.2. Het op te lossen probleem
We willen een programma schrijven dat op de avond van de verkiezingen het aantal zetels kan berekenen dat door de verschillende deelnemende lijsten is behaald. Iets verderop wordt de berekeningswijze van de zetels voor een evenredige verkiezing volgens het hoogste gemiddelde beschreven, zoals uitgelegd in een artikel in de krant Ouest-France van 15 maart 1986.
We gaan een Java-console-applicatie schrijven, c.a.d, een applicatie die via het toetsenbord en het scherm met de gebruiker communiceert. De applicatie vraagt de gebruiker om de volgende gegevens (in te voeren via het toetsenbord):
- aantal te vervullen zetels
- aantal deelnemende lijsten
- voor elke lijst: de naam en het aantal stemmen
Met deze gegevens berekent de applicatie het aantal zetels dat elke lijst heeft behaald en geeft deze op het scherm weer in de volgende vorm:
waarbij [Xi] de naam is van lijst nr. i en [Ni] het aantal zetels dat deze lijst heeft behaald.
Het artikel in Ouest-France van 15 maart 1986:


2.3. De algoritmische oplossing
Een algoritmische oplossing zou als volgt kunnen zijn:
| début-programme
// gegevens
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
// aantal te vervullen zetels
saisieOK<-faux
tant que non saisieOK
écrire "Nombre de sièges à pourvoir : "
lire nbSiègesAPourvoir
si nbSiègesAPourvoir n'est pas un entier >0 alors
écrire "Erreur : tapez un nombre entier >0"
sinon
saisieOK<-vrai
finsi
fintantque
// aantal deelnemende lijsten
saisieOK<-faux
tant que non saisieOK
écrire "Nombre de listes en compétition : "
lire nbListes
si nbListes n'est pas un entier >0 alors
écrire "Erreur : tapez un nombre entier >0"
sinon
saisieOK<-vrai
finsi
fintantque
// grootte van de tabellen
dimensionner les tableau nomListe, voixListe, elimineListe, siegesListe, moyenneListe à nbListes éléments
// invoer van namen en stemmen van de lijsten
totalVoix<-0
pour i variant de 0 à nbListes-1
// invoer van de naam van lijst 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
// het aantal stemmen van lijst i invoeren
saisieOK<-faux
tantque non saisieOK
écrire "Nombre de voix de la liste ", nomListe[i] , " : "
lire voixListe[i]
si voixListe[i] n'est pas un nombre entier >=0 alors
écrire "Erreur : tapez un nombre entier >=0"
sinon
saisieOK<-vrai
finsi
fintantque
// het totaal aantal stemmen wordt verhoogd
totalVoix<- totalVoix+voixListe[i]79.finpour 80.
// berekening van de geldige stemmen
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
// zijn er nog lijsten die niet zijn uitgeschakeld?
si nbVoixUtiles=0 alors
écrire "Erreur : toutes les listes ont été éliminées"
arrêt du programme
finsi
// verdeling van de zetels op basis van het quotiënt
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
// verdeling van de resterende zetels op basis van het hoogste gemiddelde
// bij elke lusronde wordt 1 zetel toegewezen
pour iSiège variant de 0 à nbSiègesAPourvoir - nbSiègesPourvus - 1
// zoektocht naar de lijst met het hoogste gemiddelde
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
// er wordt 1 zetel toegewezen aan de lijst met het hoogste gemiddelde
siegeListe[iMax] <- siegeListe[iMax]+1
// en het gemiddelde wordt aangepast
moyenneListe[iMax] <- voixListe[iMax]/(siegeListe[iMax]+1)
finpour
// weergave van de resultaten zonder sortering
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. Te doen
Q1: vertaal het algoritme naar C#. Implementeer het met Visual Studio.
Q2: vertaal het algoritme naar Java, waarbij je je laat inspireren door de C#-code. Implementeer het Java-programma in een Eclipse-omgeving die vergelijkbaar is met de volgende:
- [1]: het project heet [elections-01]
- [2]: de applicatie wordt in een pakket geplaatst, in dit geval [istia.st.elections]
- [3]: [MainElections.java] is de broncode van de applicatie die in het vorige deel is geschreven
- [4]: de klasse [MainElections] wordt uitgevoerd
Een voorbeeld van een uitvoering zou er als volgt uit kunnen zien:
