2. [TD]: Das Problem
Stichworte: Algorithmik, Java-Grundlagen: Arrays, E/A, Schleifen, Bedingungen, Ausnahmebehandlung
Literaturempfehlungen: Kapitel 1 aus [ref1]: Grundlagen der Programmiersprache Java
2.1. Support
Der Ordner [support / chap-02] enthält den Algorithmus, der in C# und Java umgesetzt werden soll.
2.2. Die zu lösende Aufgabe
Es soll ein Programm geschrieben werden, das am Wahlabend die Anzahl der Sitze berechnen kann, die die verschiedenen teilnehmenden Listen erhalten haben. Etwas weiter unten wird die Methode zur Berechnung der Sitze bei einer Verhältniswahl nach dem „stärksten Durchschnitt“-Verfahren beschrieben, wie sie in einem Artikel der Zeitung „Ouest-France“ vom 15. März 1986 erläutert wurde.
Wir werden eine Java-„Konsolen“-Anwendung namens c.a.d schreiben, d. h. eine Anwendung, die über Tastatur und Bildschirm mit dem Benutzer kommuniziert. Sie wird den Benutzer um folgende Angaben bitten (über die Tastatur einzugeben):
- Anzahl der zu vergebenden Sitze
- Anzahl der konkurrierenden Listen
- für jede Liste: deren Name und Stimmenzahl
Anhand dieser Angaben berechnet die Anwendung die von jeder Liste erzielten Sitze und zeigt sie auf dem Bildschirm in folgender Form an:
wobei [Xi] der Name der Liste Nr. i und [Ni] die Anzahl der Sitze ist, die sie erhalten hat.
Der Artikel in der „Ouest-France“ vom 15. März 1986:


2.3. Die algorithmische Lösung
Eine algorithmische Lösung könnte wie folgt aussehen:
| début-programme
// Daten
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
// Anzahl der zu besetzenden Sitze
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
// Anzahl der konkurrierenden Listen
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
// Größe der Tabellen
dimensionner les tableau nomListe, voixListe, elimineListe, siegesListe, moyenneListe à nbListes éléments
// Eingabe der Namen und Stimmen der Listen
totalVoix<-0
pour i variant de 0 à nbListes-1
// Eingabe des Namens der 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
// Eingabe der Stimmenzahl der Liste i
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
// Die Gesamtstimmenzahl wird erhöht
totalVoix<- totalVoix+voixListe[i]79.finpour 80.
// Berechnung der gültigen Stimmen
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
// Gibt es noch nicht ausgeschiedene Listen?
si nbVoixUtiles=0 alors
écrire "Erreur : toutes les listes ont été éliminées"
arrêt du programme
finsi
// Verteilung der Sitze nach dem Quotienten
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
// Verteilung der verbleibenden Sitze nach dem höchsten Durchschnitt
// In jeder Schleifenrunde wird 1 Sitz vergeben
pour iSiège variant de 0 à nbSiègesAPourvoir - nbSiègesPourvus - 1
// Suche nach der Liste mit dem höchsten Durchschnitt
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
// Der Liste mit dem höchsten Durchschnitt wird 1 Sitz zugewiesen
siegeListe[iMax] <- siegeListe[iMax]+1
// und ihr Durchschnitt wird geändert
moyenneListe[iMax] <- voixListe[iMax]/(siegeListe[iMax]+1)
finpour
// Anzeige der Ergebnisse ohne Sortierung
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. Aufgabe
Q1: Den Algorithmus in C# umsetzen. Ihn mit Visual Studio implementieren.
Q2: Den Algorithmus in Java umsetzen, wobei Sie sich am C#-Code orientieren. Das Java-Programm in einer Eclipse-Umgebung implementieren, ähnlich wie im folgenden Beispiel:
- [1]: Das Projekt heißt [elections-01]
- [2]: Die Anwendung wird in einem Paket abgelegt, hier [istia.st.elections]
- [3]: [MainElections.java] ist der Quellcode der im vorherigen Abschnitt geschriebenen Anwendung
- [4]: Die Klasse [MainElections] wird ausgeführt
Ein Beispiel für die Ausführung könnte wie folgt aussehen:
