Mehrheitswahl
Aufgabe
So funktioniert die Mehrheitswahl
Jede Person gibt genau eine Stimme ab. Ausgewertet wird so:
- Zählen: Jeder Stimmzettel zählt für den Kandidaten, dessen Name darauf steht. Ein Name, der nicht zur Wahl steht, ist ungültig und zählt für niemanden.
- Sieg: Es gewinnt, wer die meisten Stimmen hat. Mehr als die Hälfte der Stimmen ist dafür nicht nötig.
- Gleichstand: Haben mehrere Kandidaten die höchste Stimmenzahl, gewinnen alle gemeinsam.
Beispiel mit 9 Stimmzetteln:
| Anzahl | Stimme |
|---|---|
| 2 | Alice |
| 3 | Bob |
| 4 | Charlie |
Charlie gewinnt mit 4 von 9 Stimmen, obwohl er nicht mehr als die Hälfte hat. Bei Alice 3, Bob 3, Charlie 3 gewännen alle drei gemeinsam.
Wo die Mehrheitswahl an ihre Grenzen stößt, steht am Ende der Seite unter „Zum Weiterlesen“.
Demo
Aufgabenmaterial
Für diese Aufgabe werden Sie ein von uns zur Verfügung gestelltes Codegerüst vervollständigen.
Aufgabenmaterial herunterladen
Öffnen Sie VS CodeVisual Studio Code, der kostenlose Code-Editor von Microsoft, in dem Sie im Kurs programmieren. Glossar → entsprechend Ihrem Setup.
Öffnen Sie Ihr TerminalfensterFenster, in dem Sie dem Computer Befehle als Text eintippen statt zu klicken. In VS Code liegt es im unteren Bereich des Fensters. Glossar → und führen Sie dann cdWechselt das Verzeichnis: cd me geht in den Ordner me, cd .. eine Ebene nach oben, cd allein ins Homeverzeichnis. Glossar → aus. Die EingabeaufforderungDas Zeichen am Anfang der Zeile im Terminal, etwa $ oder me/ $. Es zeigt, dass das Terminal auf Ihren nächsten Befehl wartet. Steht davor ein Ordnername wie me/, befinden Sie sich gerade in diesem Ordner. Glossar → Ihres Terminalfensters sollte wie folgt aussehen:
$Führen Sie dann
wget https://dev.inf.zone/download/exercises/05/plurality.zipaus, um eine ZIP-Datei namens plurality.zip in den aktuellen Ordner herunterzuladen. Achten Sie darauf, dass Sie das Leerzeichen zwischen wgetLädt eine Datei aus dem Internet in das aktuelle Verzeichnis herunter, im Kurs zum Beispiel das Aufgabenmaterial einer Übung. Glossar → und der folgenden URL nicht übersehen, und auch kein anderes Zeichen!
Führen Sie jetzt
unzip plurality.zipaus, um das ZIP-Archiv in einen Ordner namens plurality zu extrahieren. Sie brauchen die ZIP-Datei nicht mehr, also können Sie
rm plurality.zipausführen. Antworten Sie mit “y”, gefolgt von der Eingabetaste, um die heruntergeladene ZIP-Datei zu entfernen.
Führen Sie dann
cd pluralityaus, um in dieses Verzeichnis zu wechseln. Ihre Eingabeaufforderung sollte nun wie folgt aussehen:
plurality/ $Wenn alles funktioniert hat, sollten Sie nach dem Ausführen von
lseine Datei mit dem Namen plurality.c sehen. Wenn Sie code plurality.c ausführen, sollte sich die Datei öffnen. In diese Datei werden Sie Ihren Code für diese Aufgabe einfügen. Wenn diese Datei nicht angezeigt wird, verfolgen Sie Ihre Schritte zurück und schauen Sie, ob Sie herausfinden können, wo Sie einen Fehler gemacht haben!
Überblick über plurality.c
Wenn Sie die Funktionalität eines bestehenden Codes erweitern wollen, sollten Sie ihn zunächst in seinem jetzigen Zustand verstehen.
Am Anfang der Datei legt #define MAX 9 die Konstante MAX fest: die höchste Zahl an Kandidaten. Mit ihr wird das globale Array candidates angelegt, auf das jede Funktion zugreifen kann.
// Max number of candidates
#define MAX 9// Array of candidates
candidate candidates[MAX];Ein candidate ist eine struct mit zwei Membern: name (ein string) und votes (ein int, die Zahl der Stimmen).
// Candidates have name and vote count
typedef struct
{
string name;
int votes;
} candidate;Die globale Variable candidate_count enthält die Zahl der Kandidaten.
// Number of candidates
int candidate_count;main kopiert die Kommandozeilenargumente in das Array candidates und setzt alle Stimmenzahlen auf 0. Ohne Argument endet das Programm mit einer Usage-Meldung (Rückgabewert 1), bei mehr als 9 Kandidaten mit Maximum number of candidates is 9 (Rückgabewert 2).
// Populate array of candidates
candidate_count = argc - 1;
if (candidate_count > MAX)
{
printf("Maximum number of candidates is %i\n", MAX);
return 2;
}
for (int i = 0; i < candidate_count; i++)
{
candidates[i].name = argv[i + 1];
candidates[i].votes = 0;
}Dann fragt main nach der Zahl der Wählenden (Number of voters: ), liest für jede Person einen Namen ein (Vote: ) und ruft damit vote auf. Gibt vote den Wert false zurück, gibt main Invalid vote. aus. Zum Schluss ruft main die Funktion print_winner auf.
Weiter unten stehen die beiden Funktionen, die Sie ausfüllen:
// Update vote totals given a new vote
bool vote(string name)
{
// TODO
return false;
}
// Print the winner (or winners) of the election
void print_winner(void)
{
// TODO
return;
}Spezifikation
Ändern Sie in plurality.c nur die Funktionen vote und print_winner (zusätzliche Header-Dateien dürfen Sie einbinden). Wenn Ihr Ansatz nur mit einer Änderung an anderer Stelle funktioniert, überdenken Sie ihn.
vote(name): Stimmtnamegenau mit dem Namen eines Kandidaten überein, erhöhen Sie dessenvotesum 1 und gebentruezurück. Sonst ändert sich nichts, und die Funktion gibtfalsezurück. Groß- und Kleinschreibung zählt:aliceist keine Stimme fürAlice. Sie können davon ausgehen, dass keine zwei Kandidaten denselben Namen haben.print_winner(): gibt den Namen des Kandidaten mit den meisten Stimmen aus, gefolgt von einem Zeilenumbruch. Haben mehrere Kandidaten die höchste Stimmenzahl, gibt sie jeden dieser Namen in einer eigenen Zeile aus.
So sieht ein Lauf mit Gleichstand und einer ungültigen Stimme aus:
$ ./plurality Alice Bob Charlie
Number of voters: 5
Vote: Alice
Vote: Bob
Vote: Alice
Vote: Dave
Invalid vote.
Vote: Bob
Alice
BobHilfestellung
Klicken Sie auf die folgenden Tipps, um einige Ratschläge zu erhalten. Versuchen Sie aber zunächst, selbst so weit wie möglich zu kommen.
Implementierung der vote-Funktion
Eine Möglichkeit, dieses Problem anzugehen:
- Iterieren über jeden Kandidaten
- Prüfen, ob der Name des Kandidaten mit der Eingabe
nameübereinstimmt- Wenn ja, Stimmen dieses Kandidaten erhöhen und
truezurückgeben - Wenn nein, weiter prüfen
- Wenn ja, Stimmen dieses Kandidaten erhöhen und
- Prüfen, ob der Name des Kandidaten mit der Eingabe
- Gab es nach der Prüfung aller Kandidaten keine Übereinstimmung,
falsezurückgeben
Schreiben Sie diese Schritte als Pseudocode in die Datei und implementieren Sie sie dann der Reihe nach.
// Update vote totals given a new vote
bool vote(string name)
{
// Iterate over each candidate
// Check if candidate's name matches given name
// If yes, increment candidate's votes and return true
// If no match, return false
}Zwei Zeichenketten vergleichen Sie mit strcmp, nicht mit ==.
Implementierung der print_winner-Funktion
Vielleicht denken Sie zuerst an einen Sortieralgorithmus: die Kandidaten nach ihrer Stimmenzahl sortieren und dann den Spitzenkandidaten (oder die Spitzenkandidaten) ausgeben. Sortieren ist aber aufwendig: Selbst Merge Sort, einer der schnellsten Sortieralgorithmen, läuft in .
Eigentlich brauchen Sie nur zwei Informationen:
- die höchste Stimmenzahl unter den Kandidaten,
- den Kandidaten (oder die Kandidaten) mit dieser Stimmenzahl.
Eine gute Lösung kommt daher mit zwei Durchläufen über das Array aus (jeweils ):
// Print the winner (or winners) of the election
void print_winner(void)
{
// Find the maximum number of votes
// Print the candidate (or candidates) with maximum votes
}Den konkreten Code überlassen wir Ihnen!
Testen
Stellen Sie beim Testen Ihres Codes sicher, dass dieser mit folgenden Szenarien umgehen kann:
- einer Wahl mit einer beliebigen Anzahl von Kandidaten (bis zum
MAXvon9) - der Stimmabgabe für einen Kandidaten nach Namen
- ungültigen Stimmen für Kandidaten, die nicht auf dem Stimmzettel stehen (das Programm gibt
Invalid vote.aus und macht mit der nächsten Person weiter) - der Ausgabe des Gewinners der Wahl, wenn es nur einen gibt
- der Ausgabe der Gewinner der Wahl (jeweils in einer eigenen Zeile), wenn es mehrere gibt
Korrektheit
Führen Sie in Ihrem Terminal den folgenden Befehl aus, um die Korrektheit Ihrer Arbeit zu überprüfen:
check50 -l inf-zone/exercises/2026/pluralityStyle
Führen Sie den folgenden Befehl aus, um den Stil Ihres Codes mit style50Prüfprogramm von CS50, das zeigt, wo Ihr Code von den Formatierungsregeln abweicht. In Grün zeigt es, was Sie ergänzen sollten, in Rot, was wegfallen soll. Glossar → zu analysieren:
style50 plurality.cAbgeben
Geben Sie im Ordner plurality ab:
inf upload pluralityDanach sehen Sie, welche Tests Ihr Programm besteht und ob die Übung für die Bonuspunkte zählt. Wie Sie inf installieren und sich anmelden, steht unter Abgeben mit inf.
Zum Weiterlesen: Wahlverfahren
Für die Lösung der Aufgabe nicht nötig.
Wahlen gibt es in allen Formen und Größenordnungen. Im Vereinigten Königreich wird der Premierminister offiziell vom Monarchen ernannt, der in der Regel den Führer der politischen Partei wählt, die die meisten Sitze im Unterhaus gewinnt. In den Vereinigten Staaten gibt es ein mehrstufiges Electoral College, in dem die Bürger darüber abstimmen, wie die einzelnen Bundesstaaten die Wahlmänner verteilen sollen, die dann den Präsidenten wählen.
Die Mehrheitswahl (auch „Pluralitätswahl“, englisch plurality, first-past-the-post oder winner take all) ist wohl die einfachste Art, eine Wahl abzuhalten. Sie hat aber einen Haken: Im Beispiel oben gewinnt Charlie mit 4 von 9 Stimmen, obwohl die Mehrheit (5 von 9) jemand anderen gewählt hat. Die integrierte Stichwahl berücksichtigt deshalb auch die weiteren Präferenzen der Wählenden – im Beispiel dort (dieselben ersten Präferenzen) gewinnt Bob, weil die zwei Stimmen für Alice an ihre 2. Präferenz Bob gehen.
Diese Seite als Markdown: ansehen herunterladen