SS 2004 Technische Universität Darmstadt FB Mathematik, AG 7, Diskrete Optimierung Prof. Dr. Alexander Martin Daniel Junglas Lars Schewe 3. Übung Computerorientierte Mathematik Praxis P1. Euklidischer Algorithmus Schreiben Sie ein Programm das wie folgt funktioniert: (a) Von der Tastatur werden zwei positive ganze Zahlen a und b eingelesen. (b) Ist a = 0 oder b = 0, dann wird das Programm beendet. (c) Das Programm berechnet ggT(a, b) und kgV(a, b) und gibt beide aus. (d) Danach wird bei Schritt 1a weitergemacht. Das geschriebene Programm soll die folgenden Anforderungen erfüllen • Ist a <= 0 oder <= 0, dann wird das Programm sofort mit einer entsprechenden Fehlermeldung beendet. • Das Programm soll eine Funktion int euclid (int a, int b) enthalten, die ggT(a, b) mit Hilfe des euklidischen Algorithmus’ berechnet und zurückgibt. • Zur Berechnung von kgV(a, b) soll ebenfalls euclid verwendet werden. Eine kurze Beschreibung des (erweiterten) euklidischen Algorithmus finden Sie z.B. hier: http://www-math.cudenver.edu/˜wcherowi/courses/m5410/exeucalg.html P2. Kommandozeilen-Argumente Statt einer Funktion int main (void) kann man auch eine Funktion int main (int argc, char* argv[]) definieren. (a) Was für ein Typ ist argv? (b) Sehen Sie unter man 3 printf nach, was das Format ,,%s” in der printf()-Anweisung bedeutet. (c) Implementieren Sie das Programm (list.c) #include <stdio.h> int main (int argc, char* argv[]) { int i; for (i = 0; i < argc; i++) { printf("%d: %s\n", i, argv[i]); } return 0; } und führen Sie die folgenden Befehle aus: fb04305: fb04305: fb04305: fb04305: fb04305: ~ ~ ~ ~ ~ > > > > > ./list ./list ./list ./list ./list 1 -l -o Datei -p dies sind einige Worte Was ist argc und was ist argv? (d) Schreiben Sie ein Programm calculate das den folgenden Anforderungen genügt: • Das Programm erwartet immer genau drei Argumente auf der Kommandozeile: das erste und das letzte Argument müssen eine Zahl sein, das zweite Argument ist einer der Buchstaben ’+’, ’-’, ’/’ oder ’*’. Werden zuwenige oder falsche Argumente angegeben, dann wird das Programm mit einer entsprechenden Fehlermeldung beendet. Der Einfachheit halber können Sie für ’/’ in Ihrem Programm ganzzahlige Division verwenden. • Das Programm berechnet den auf der Kommandozeile angegebenen arithmetischen Ausdruck und gibt das Ergebnis aus. Die Ausgabe soll in etwa so aussehen: fb04305: ~ > ./calculate 4 + 5 4 + 5 = 9 fb04305: ~ > • freiwillig Das Programm soll den Operator ’ˆ’ als ,,hoch” interpretieren und damit auch Potenzen wie 23 berechnen können. P3. Strings Mit Hilfe von char input[21]; ... scanf("%20s", input); kann ein bis zu 20 Zeichen langer String von der Tastatur eingelesen werden (wegen des 0-Bytes am Ende eines jeden Strings, muss input um eins größer als die Anzahl der einzulesenden Zeichen sein). Eingebenen Strings, die länger als 20 Zeichen sind, werden nach dem 20ten Zeichen abgeschnitten bzw. erst beim nächsten Aufruf von scanf() betrachtet. Die eingegebenen Strings dürfen ausserdem keine Whitespaces beinhalten. Schreiben Sie ein Programm str-stats, das • in einer Schleife jeweils einen maximal 80 Zeichen langen String von der Tastatur einliest, bis ein String eingegeben wurde, der nur aus einem Punkt besteht. • Für jeden String die Länge des Strings ausgibt. • Für jeden Buchstaben, der in dem String auftritt, angibt wie oft er auftritt. • Den String von hinten nach vorne ausgibt. P4. Bearbeiten Sie alle Praxisaufgaben der letzten Blätter, die Sie noch nicht bearbeitet haben. Vorbereitung der nächsten Vorlesung In den folgenden Programmen sind einige syntaktische und/oder logische Fehler versteckt. Finden Sie jeweils so viele wie möglich. Versuchen Sie, die Fehler zunächst auf dem Papier zu finden. Danach können Sie die Programme von der Website der Veranstaltung herunterladen und mit Hilfe des Editors/Compilers auf Fehlersuche gehen. prozent.c Es werden zwei Zahlen a und b eingelesen. Dann wird ausgegeben, wieviel b Prozent von a sind. Für a = 4 und b = 50 soll das Ergebnis also 2 sein. #include <stdio.h> int main (void) { do { int a, b, c; printf("a? "); scanf("%d", &a); printf("b? "); scanf("%d", &b); c = (b / 100) * a; printf("%d Prozent von %d = %d\n", b, a, c); } while (a != 0); return 0; } print-number Für eine einzulesende Zahl i soll für jede Dezimalziffer das entsprechende Zahlwort ausgegeben werden: Zahl: 123 eins zwei drei Es kann angenommen werden, dass die eingegebenen Zahlen nicht negativ sind (,,0” ist allerdings eine erlaubte – daher das ,,if”). #include <stdio.h> int main (void) { int i; char* words[10] = { "null", "eins", "zwei", "drei", "vier", "funf", "sechs", "sieben", "acht", "neun" }; printf("Zahl: "); scanf("%d", i); if (i = 0) printf("%s\n", words[0]); return 0; while (i) { printf("%s", words[i / 10]); i = i % 10; } return 0; } (Es wäre natürlich schön, auch Spezialfälle wie ,,elf” oder ,,zwölf korrekt zu behandeln. Der Einfachheit halber verzichten wir darauf aber.) ggt.c Der ggT von zwei eingegebenen Zahlen soll berechnet werden. Dabei wird davon ausgegangen, dass die beiden Zahlen positiv sind. #include <stdio.h> void ggT (int a, int b) { if (a < b) a = b; b = a; while (b > 0) if (a > b) a -= b; else b -= a; } int main (void) { int a, b; scanf("%d", &a); scanf("%d", b); printf("ggT(%d,%d) = ", a, b); ggT(a, b); printf("%d\n", a); return 0; } marks.c Für jedes Argument der Kommandozeile soll die Anzahl der Frage- und Ausrufezeichen bis zum Auftreten des ersten Doppelpunktes bestimmt werden. #include <stdio.h> int main (int argc, char* argv[]) { int i; for (i = 0; i < argc; i++) { int j = 0; int weiter = 1; char* s = argv[i]; int count = 0; printf("’%s’: ", argv[i]); while (weiter = 1) { if (s[j] == ’:’) weiter = 0; if ((s[j] == ’!’) || (s[j++] == ’?’)) count = count + 1; } printf("Frage-/Ausrufezeichen bis zum ersten ’:’ %d\n", count); } } double.c Es sollen die Zahlen 0.0, 0.1 usw. bis 0.9 ausgegeben werden. #include <stdio.h> int main (void) { double d; for (d = 0.0; d != 1.0; d = d + 0.1) printf("%f\n", d); return 0; }