Ziele sind das Arbeiten mit Funktionen und dem Aufzählungstyp (enum), sowie - einfache Verzweigung (if else) - Alternativen switch case - einfache Schleifen (while oder do while) Aufgabe 3: Diese Aufgabe basiert auf der Aufgabe 2. Es ist ein Programm zu erstellen, in welchem der Anwender aus einer Anzahl möglicher Aktionen eine Aktion auswählen kann (Menüsteuerung). Danach wird die gewählte Aktion durchgeführt und erneut die Auswahl angeboten. Dies wird solange durchgeführt, bis der Anwender entscheidet, dass das Programm beendet werden soll. Folgende Aktionen sollen zur Auswahl stehen und mittels switch case realisiert werden: 1. Lösungen einer quadratischen Gleichung (p/q-formel) berechnen und ausgeben 2. Mittelwert spezial berechnen und ausgeben 3. Binomialkoeffizient (=Pascalsches Dreieck) berechnen und ausgeben 4. Exponentialfunktion e x berechnen und ausgeben 5. Das Programm beenden Hinweise zur Lösung: Beginnen Sie mit dem Auswahlmenü und fügen Sie zunächst nur einfache Textausgaben wie Berechnung der e-funktion anstelle der eigentlichen Funktionalität ein. Ersetzen Sie danach eine mathematische Funktion nach der anderen mit echter Funktionalität. Die Reihenfolge können Sie frei wählen. Das gelingt am einfachsten, wenn Sie ein neues Projekt anlegen und dann die Aufgabe 2 hinein kopieren. Löschen Sie dann einfach die Anweisungen innerhalb der switch()-struktur, die nicht mehr zur neuen Aufgabenstellung passen. Es ist für die Lösung der Programmieraufgabe nicht nötig, den mathematischen Hintergrund zu verstehen, es kann aber beim Verständnis helfen. Hinweise zur Gestaltung des Programms: a) Das Menü selbst soll als Funktion implementiert werden. b) Die Menüpunkte 1 bis 4 sollen als Funktionsaufruf realisiert werden. c) Alle Funktionsprototypen sollen in einer Header-Datei (z.b. dritteaufgabe.h) angegeben werden. siehe auch letzte Seite d) Alle Funktionen sollen in einer Quell-Datei (z.b. dritteaufgabe.cpp) implementiert werden. e) Das Hauptprogramm (Funktion main) steht in einer eigenen Datei (z.b. main.cpp). Zu 1. Lösungen einer quadratischen Gleichung berechnen und ausgeben Die Lösungen einer quadratischen Gleichung der Form x 2 + p x + q = 0 sind bekanntlich X 1 = p/2 + ((p/2) 2 q) bzw. X 2 = p/2 ((p/2) 2 q) Für einzugebende Werte p und q sollen x 1 und x 2 berechnet und ausgegeben werden. Bei der Berechnung sind per if... else drei Fälle zu unterscheiden: - der Ausdruck unter der Wurzel ist positiv; d.h. das Ergebnis kann berechnet werden - der Ausdruck unter der Wurzel ist negativ; d.h. Ausgabe einer entsprechenden Fehlermeldung - der Ausdruck unter der Wurzel ist 0 (null); d.h. das Ergebnis kann vereinfacht berechnet werden Seite 1 von 6
Als Vergleichswerte sollen diesmal die Werte des Aufzählungstyps diskrimantewert verwendet werden. Das Programm soll die Werte p und q im Hautprogramm über die Tastatur einlesen und die entsprechenden Wertepaare p, q sowie x 1 und x 2 im Hauptprogramm auf dem Bildschirm ausgeben. Für die Berechnung der Wurzel... benö gt man die Funk on f(x) = (x), sie wird aus der Standardbibliothek für mathematische Funktionen mit der Kennung <cmath> zum Programm hinzu gebunden und kann dann mit dem Namen sqrt(x) aufgerufen werden. Zu 2. Mittelwert spezial berechnen und ausgeben Der normale Mittelwert wird berechnet als Summe aller angegebenen Werte, dividiert durch die Anzahl dieser Werte. Unser Mittelwert spezial wird bei einigen Sportarten (z.b. Skispringen und Eiskunstlauf) eingesetzt und mittelt bei Ausreißern in den Werten besser, weil er den höchsten und den niedrigsten der eingegebenen Werte ignoriert. Das Programmteil soll vom Anwender die Anzahl der Werte erfragen (max. 10). Danach die einzelnen Werte abfragen und in einem Feld (array) ablegen. Im zweiten Schritt werden dann der höchste und der niedrigste Wert der Reihe durch Null ersetzt, die Summe berechnet und dann durch die Anzahl der Werte -minus 2- dividiert. Beispiel mit 8 Werten: 14 3 17 10 22 108-17 7 Der klassische Mittelwert beträgt hier (14 + 3 + 17 + 10 + 22 + 108 + (-17) + 7) / 8 und liegt damit bei 164 / 8 = 20,5. Für den Mittelwert spezial werden der höchste (108) und der niedrigste Wert (-17) auf Null gesetzt: 14 3 17 10 22 0 0 7 Die Addition aller Werte ergibt also jetzt (14 + 3 + 17 + 10 + 22 + 0 + 0 + 7) = 73, und dividiert wird jetzt durch 8-2, also durch 6. Das ergibt dann 73 / 6=12,166. ACHTUNG!! Erweitern Sie Ihr Programm aus Aufgabe 2 dahingehend, dass der Anwender bei der Eingabe der Anzahl der Werte nur gültige Zahlenwerte zwischen 3 und maximale Feldgröße = 10 eingeben kann. Zu 3. Binomialkoeffizient (=Pascalsches Dreieck) berechnen und ausgeben Wikipedia sagt dazu: Der Binomialkoeffizient ist eine mathematische Funktion, mit der sich eine der Grundaufgaben der Kombinatorik lösen lässt. Er gibt an, auf wie viele verschiedene Arten man Objekte aus einer Menge von verschiedenen Objekten auswählen kann (ohne Zurücklegen, ohne Beachtung der Reihenfolge). Der Binomialkoeffizient ist also die Anzahl der -elementigen Teilmengen einer - elementigen Menge. Wir beschränken uns auf einen Nebeneffekt, die Koeffizienten für die Binomischen Formeln, die man aus dem Pascal'schen Dreieck entnehmen kann. Ihre Aufgabe ist es, das Pascal'sche Dreieck zu berechnen und optisch ansprechend auszugeben. Das Ergebnis sollte als in etwa so aussehen und die ersten 10 Reihen enthalten: Seite 2 von 6
Hinweise zur Lösung: Wie man sieht, ergibt sich eine Zahl im Dreieck als Summe der beiden darüber stehenden Werte. Diese Dreiecksform ist aber im Rechner nur schlecht nachzubilden, da sieht das Dreieck etwas anders aus. Ihr Programm sollte auf einem Feld (array) basieren, das zum Start mit der Folge {1,0,0,0,0,0,0,0 } initialisiert wurde. Hier die Darstellung im Speicher des Computers: 1 0 0 0 0 0 0 0 0 0 Nach dem ersten Schritt sieht das dann so aus: 1 1 0 0 0 0 0 0 0 0 Und so weiter 1 2 1 0 0 0 0 0 0 0 1 3 3 1 0 0 0 0 0 0 1 4 6 4 1 0 0 0 0 0 Der Algorithmus addiert also die Werte an der Position n und n+1 und schreibt das Ergebnis an die Position n+1. Der Wert an Position 1 bleibt unverändert. Überlegen Sie genau, in welcher Reihenfolge/Richtung das Feld durchlaufen werden muss! Wenn Sie eine andere Lösung entwickeln und/oder ihr Verfahren eine andere Initialisierung erfordert, dürfen Sie die natürlich verwenden. Es handelt sich hier nur um einen Vorschlag! Wenn Ihnen die Verarbeitung in nur einem Feld nicht ausreichend klar ist, dürfen Sie auch mit einem Hilfsfeld bei der Berechnung arbeiten und die Werte danach umkopieren. Erst wenn die Koeffizienten korrekt sind, verbessern Sie die Form der Ausgabe. Um die Ausgabe optisch zu gestalten verwenden Sie die Anweisung setw(feldbreite) aus der Bibliothek <iomanip>. Details dazu finden Sie z.b. unter www.cplusplus.com/reference/iomanip/setw/ Vor der Ausgabe des ersten Wertes geben Sie eine (berechnete) Folge von Leerzeichen aus. Der Bildschirm für Ihre Ausgabe umfasst übrigens 25 Zeilen mit Platz für 80 Zeichen. Die Formel zur Berechnung der Abstände und Feldbreiten sollten Sie sich bereits zu Hause überlegen. Seite 3 von 6
Zu 4. Exponentialfunktion e x berechnen und ausgeben Die Mathematiker schreiben Funktionen gerne als Reihenentwicklung, auch ein Computer nutzt dieses Verfahren, um die Funktionswerte näherungsweise zu bestimmen. Die Exponentialfunktion sieht dann so aus: exp(x)= x i x2 = 1+x+ i= 0 i! 2! + x3 3! + x4 4! + Verwenden Sie für die Reihenberechnung lediglich eine Schleife und die Grundrechenarten; d.h. keine pow- Funktion (z.b. x 5 ) verwenden und keine Fakultätsberechnung durchführen. Brechen Sie die Schleife ab, wenn der zu berechnete Summand kleiner als ein vom Benutzer vorgegebener Wert epsilon oder wenn die vom Benutzer vorgegebene Anzahl von Schritten erreicht ist. Es sollen sowohl der berechnete Wert e_hoch_x als auch der exakte Wert über exp(x) aus <cmath> ausgegeben werden. Hinweis zum Testen: Für x = 1 sollte die Eulersche Zahl so gut es geht näherungsweise berechnet werden Headerdatei dritteaufgabe.h Aus didaktischen Gründen ist folgende Header-Datei zu verwenden, d.h. viele Varianten für Funktionsaufrufe und Rückgabewerte sollen gelernt werden. #include <iostream> #include <iomanip> #include <cmath> using namespace std; // der Aufzählungstyp enum diskriminantewert { GLEICHNULL, NEGATIV, POSITIV }; // die Funktionsprototypen char Menu(); // oder alternativ: int Menu(); // Rückgabewert ist der entsprechende Menüpunkt diskriminantewert PQFormel(double p, double q, double & x1, double & x2); // Rückgabewert ist der Bereichswert der Diskriminante double MittelwertSpezial( int feld[], int anzahl, const int MINVALUE, const int MAXVALUE ); // Rückgabewert ist der berechnete Mittelwert void PascalDreieck( int dreieck[], const int MAXVALUE ); // Funktion hat keinen Rückgabewert double Exponentialfunktion( int x, int schritte, double epsilon ); // Rückgabewert ist der berechnete Näherungswert von exp(x) Seite 4 von 6
Beispiel eines Hauptprogrammrahmens (Menüsteuerung): // Aufgabe3 - Sommersemester 2016 // Autoren: Jörg Schake, Dirk Seeber #include <iostream> #include <iomanip> #include <cmath> using namespace std; int main() { // Variablendeklaration char menu; bool programmende = false; diskriminantewert rueckgabepqformel; // weitere Variablen do { menu = Menu(); // Fallunterscheidung switch (menu) { case '1': // Ihre Implementierung der p/q-formel // Eingabe der Werte für p und q // Berechnung der Werte für x1 und/oder x2 rueckgabepqformel = PQFormel(...); // Ausgabe aller Werte case '2': // Ihre Implementierung des Mittelwert Spezial mittelwert = MittelwertSpezial(...); // Ausgabe des veränderten Feldes sowie des berechneten Mittelwerts case '3': // Ihre Implementierung des Pascal Dreiecks // Aufruf der Funktion PascalDreieck PascalDreieck(...); case '4': // Ihre Implementierung der Exponentialfunktion // Eingabe der Werte für x, epsilon und schritte // Berechnung der Werte für e_hoch_x e_hoch_x = Exponentialfunktion(...); exp_von_x = exp( x ); // Ausgabe der berechneten Werte Seite 5 von 6
} case '9': // Programm beenden programmende = true; default: // Warnhinweis cout << "Der eingegebene Wert " << menu << " ist nicht gueltig!" << endl; } // endswitch } while ( false == programmende ); system("pause"); return 0; Seite 6 von 6