Übung 3
- Bearbeiten Sie Sortieren.
- Bearbeiten Sie Mehrheitswahl.
- Bearbeiten Sie Integrierte Stichwahl.
- Testen Sie sich mit Stadt, Land, Fluss (siehe Checks).
Warm-Up-Aufgaben
Erstellen Sie für jede Übungseinheit jeweils eine eigene Datei für die Warm-Up-Aufgaben in dem Projektverzeichnis, in dem Sie auch die Übungsaufgaben bearbeiten werden.
Weitere Informationen finden Sie in diesem FAQ (Warm-Up-Aufgaben).
Als kompilierbares Codegerüst können Sie zu Beginn folgendes Snippet in Ihre Datei kopieren:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
return 0;
}
Beachten Sie insbesondere den Import der CS50-Bibliothek und der “Standard Input and Output”-Bibliotheken.
Warm-Up 1
In C kann man eine struct
definieren, um zusammengehörige Informationen besser zu verwalten.
Die nachfolgend definierte struct
enthält etwa einen string
namens name
und einen int
namens age
. Durch die Verwendung von typedef
wird diese struct
als ein uns zusätzlich zur Verfügung stehender Datentyp person
definiert (weitere Details hierzu gibt es im weiteren Verlauf des Kurses, sind aber an dieser Stelle noch nicht relevant).
// Person has name and age
typedef struct
{
string name;
int age;
} person;
int main(void)
// ...
Kopieren Sie diese struct
-Definition in Ihre Datei oberhalb der main
-Funktion.
Erstellen Sie in der main
-Funktion eine Variable vom Typ person
namens person1
und weisen Sie den Membern (d.h.name
und age
) die Werte Bob
und 37
zu.
Geben Sie diese anschließend mit
printf("Name: %s\nAlter: %i\n", /* zu ergänzen */);
aus:
Name: Bob
Alter: 37
Wo zu finden?
struct
s gibt es auch in der Section 3.
Warm-Up 2
Deklarieren Sie ein Array als globale Variable vom Typ person
namens people
der Größe MAX_PEOPLE
. Legen Sie daher außerdem eine globale Konstante namens MAX_PEOPLE
mit dem Wert 3
an. Erinnern Sie sich, dass Sie eine symbolische Konstante mittels #define [NAME] [WERT]
erstellen können.
Verwenden Sie das folgende Snippet, um dem Array in der main
-Funktion entsprechende Werte zuzuweisen:
people[0] = person1;
people[1].name = "Alice";
people[1].age = 31;
people[2].name = "Eve";
people[2].age = 32;
Geben Sie anschließend die Daten der zweiten Person mit dem entsprechend angepassten printf
wie zuvor aus:
Name: Alice
Alter: 31
Wo zu finden?
Bei Problemen und Unklarheiten schauen Sie sich am besten noch einmal die Folien und Notizen zur Vorlesung 3. Algorithmen an. Erklärungen zu struct
s gibt es auch in der Section 3. Das Anlegen von symbolischen Konstanten wurde im Short zu den Magic Numbers erklärt.
Sie haben den Unterschied zwischen lokalen und globalen Variablen noch nicht verstanden? Dann ist jetzt ein guter Zeitpunkt, um noch einmal das entsprechende Short Scope anzusehen.
Warm-Up 3
Erstellen Sie eine Funktion void find_person_with_name(string name)
, die über das Array people
iteriert und die Person mit dem eingegebenen Namen sucht. Erinnern Sie sich an die Funktion strcmp
zum Vergleichen von Strings (erfordert die Einbindung von <string.h>
). Was gibt strcmp
zurück, wenn zwei Strings gleich sind?
Wenn der Name in dem people
-Array gefunden wurde, geben Sie den Namen und das Alter wie zuvor aus (verschieben Sie dazu einfach das printf
aus der main
-Funktion und passen Sie es an). Anschließend können Sie die Funktion sofort mit return;
beenden. Wenn der Name nach dem Durchlaufen der Schleife nicht gefunden wurde, soll Der Name wurde nicht gefunden.\n
vor dem return
en der Funktion ausgegeben werden.
Die Funktion können Sie in der main
-Funktion mit find_person_with_name(argv[1]);
aufrufen. Den gesuchten Namen übergeben Sie also einfach als Kommandozeilenargument. Auf eine Verifizierung der Argumente können Sie im Rahmen dieser Warm-Up-Aufgaben verzichten. Sie müssen jedoch noch die Signatur der main
-Funktion anpassen, um Kommandozeilenargumente entsprechend verarbeiten zu können.
Strg+Shift+C
und Strg+Shift+V
(bei Windows, ansonsten rechter Mausklick in das Terminalfenster) kann man Text in die Kommandozeile kopieren. Zuvor genutzte Befehle kann man mit den Pfeiltasten (hoch/runter) oder Strg+R
erneut aufrufen.
Bei der Eingabe Eve
sollte folgendes ausgegeben werden:
Name: Eve
Alter: 32
Bei der Eingabe Mallory
sollte folgendes ausgegeben werden:
Der Name wurde nicht gefunden.
Bei der Eingabe bob
sollte folgendes ausgegeben werden (strcmp
ist case-sensitive!):
Der Name wurde nicht gefunden.
Wo zu finden?
Bei Problemen und Unklarheiten schauen Sie sich am besten noch einmal die Folien und Notizen zu den verschiedenen Versionen des Programms search.c
aus der Vorlesung 3. Algorithmen sowie das Short zur Linearen Suche an. Weitere Erklärungen zum Umgang mit struct
s gibt es auch in der Section 3. Die Funktion und Verwendung von strcmp
finden Sie auch im CS50 Handbuch.
Sie haben noch nicht verstanden, wie Sie Argumente über die Kommandozeile übergeben und in Ihrem Programm verarbeiten können? Dann ist jetzt ein guter Zeitpunkt, um noch einmal das entsprechende Short Kommandozeilenargumente anzusehen.
Warm-Up 4
Ergänzen Sie die eingangs angelegte struct
Definition um ein string
-Array namens hobbies
. Die maximale Anzahl von hobbies
soll über eine Konstante MAX_HOBBIES
auf 3
festgesetzt werden.
So sollte Ihre angepasste struct
aussehen:
#define MAX_PEOPLE 3
#define MAX_HOBBIES 3
// Person has name, age and hobbies
typedef struct
{
string name;
int age;
string hobbies[MAX_HOBBIES];
} person;
Diesem Member können Sie mit dem folgenden Snippet Werte zuweisen:
people[0].hobbies[0] = "Programmieren";
people[0].hobbies[1] = "Kochen";
people[0].hobbies[2] = "Lesen";
people[1].hobbies[0] = "Schwimmen";
people[1].hobbies[1] = "Lesen";
people[1].hobbies[2] = "Programmieren";
people[2].hobbies[0] = "Fotographie";
people[2].hobbies[1] = "Programmieren";
people[2].hobbies[2] = "Kartenspiele";
Schreiben Sie eine Funktion int count_hobby(string hobby)
, die über den Datensatz iteriert und zählt, wie viele Personen das gesuchte Hobby ausüben. Wird das Hobby bei einer der Personen gefunden, geben Sie wie zuvor die Daten zu dieser Person (d.h. name
und age
, nicht die hobbies
) aus. Geben Sie am Ende die entsprechende Häufigkeit des Hobbys zurück.
Pseudocode
Sie können sich an dem folgenden (etwas detaillierteren) Pseudocode orientieren. Die Funktion benötigt folgende Elemente:
- Eine Variable
count
, die beim Finden des Hobbys erhöht wird. - Eine Schleife, die über das
people
-Array iteriert.- Eine darin verschachtelte Schleife, die für jede
person
impeople
-Array über diehobbies
dieserperson
iteriert.- Eine Bedingung, die prüft, ob ein Hobby dieser
person
, d.h.people[i].hobbies[j]
, mit dem gesuchten Hobby übereinstimmt.- Im Falle von
true
: Die Erhöhung voncount
um1
. - Den
printf
-Aufruf, den Sie vonfind_person_with_name()
übernehmen können.
- Im Falle von
- Eine Bedingung, die prüft, ob ein Hobby dieser
- Eine darin verschachtelte Schleife, die für jede
- Die Rückgabe von
count
am Ende.
Die Funktion können Sie in der main
-Funktion mit int count = count_hobby(argv[1]);
aufrufen. Das gesuchte Hobby übergeben Sie wieder als Kommandozeilenargument. Geben Sie schließlich das Ergebnis mit
printf("Das Hobby %s wurde %i mal gefunden.\n", argv[1], count);
aus - und kommentieren Sie am besten noch den Aufruf von find_person_with_name()
aus.
Bei der Eingabe von Programmieren
:
Name: Bob
Alter: 37
Name: Alice
Alter: 31
Name: Eve
Alter: 32
Das Hobby Programmieren wurde 3 mal gefunden.
Bei der Eingabe von Kartenspiele
:
Name: Eve
Alter: 32
Das Hobby Kartenspiele wurde 1 mal gefunden.
Bei der Eingabe von Backen
:
Das Hobby Backen wurde 0 mal gefunden.
Wo zu finden?
struct
s gibt es auch in der Section 3. Vollziehen Sie ggf. noch einmal den Code von Warm-Up 3 nach. Welcher Unterschied besteht? Wie müssen Sie das Vorgehen anpassen?
Warm-Up 5
Erhöhen Sie MAX_HOBBIES
von 3
auf 5
.
Fügen Sie den Hobby-Arrays die folgenden Werte hinzu:
people[0].hobbies[3] = "Programmieren";
people[0].hobbies[4] = "Kochen";
people[1].hobbies[3] = "Schwimmen";
people[1].hobbies[4] = "Programmieren";
people[2].hobbies[3] = "Kartenspiele";
people[2].hobbies[4] = "Fotographie";
Wie Sie vielleicht bemerkt haben, enthält der Datensatz nun Duplikate. Eine Person hat das gleiche Hobby mehrmals in ihrem Hobby-Array. Dies würde die Zählung verfälschen, da gezählt werden soll, wie viele Personen ein bestimmtes Hobby haben.
Ergänzen Sie count_hobby()
so, dass sobald ein Hobby bei einer Person gezählt wurde, die Zählung für diese Person sofort beendet wird, um Doppelzählungen zu vermeiden.
Tipp: Erinnern Sie sich daran, dass man mit break;
das Durchlaufen einer Schleife vorzeitig beenden kann.
Bei der Eingabe von Programmieren
:
Das Hobby Programmieren wurde 3 mal gefunden.
Bei der Eingabe von Kartenspiele
:
Das Hobby Kartenspiele wurde 1 mal gefunden.
Bei der Eingabe von Backen
:
Das Hobby Backen wurde 0 mal gefunden.
Wo zu finden?
break
wurde im Short zu Schleifen erklärt.