/********************************************** * Beispiel: 1002 - Tantrap * Aufgabe: Zeichen mit Suchbegriff vergleiche * Autor: Martin Pickelbauer * Matrikel-Nummer: 0326586 * Mail: e0326586@student.tuwien.ac.at * Project started: 23.11.2003 **********************************************/ kurze Infos Vorweg: 1. meinen Sourcecode gibt es auch KOMPLETT kommentiert inklusive Testausgaben am Ende dieses Dokuments bzw. bitte mich kurz kontaktieren, dann kann ich dir den Code natürlich auch schicken 2. jegliche Rechtschreibfehler sollen bitte überlesen werden ;) ---------------------------------------------------------- Nun zum Programmaufbau: Ich soll zu erst einen Datensatz einlesen und diesen dann nach bestimmten Kriterien überprüfen und schließlich mit der Formel das Ergebnis berechnen. Zu erst werden die 2 Grenzen eingelesen und dann die Grenzen nach der Größe geordnet, wenn die Grenzen gleich sind (gleicheGrenzen = true), wird das Ergebnis sofort auf "0" gesetzt. Wenn die 2 Grenzen in Ordnung sind, wird das Polynom eingelesen und zwar Koeffizient, Exponent, Koeffizient, Exponent, ... usw. Dazu habe ich ein Array genommen, wobei der Array-Index = dem Exponent sein soll (also z.B.: x^2 gehört zu array[2]). Der erste Koeffizient wird eingelesen und geprüft, ob er eh nicht gleich dem Endzeichen ist (dies würde auftreten, wenn nur 2 grenzen und das Endzeichen eingegeben werden würde, also z.B.: 2.0 5.0 100) -> würde dies zutreffen, wird das Einlesen sofort Beendet (sofortEnde = true). Wenn der erste Koeffizient != Endzeichen ist, beginnt die While-Schleife, die so lange einen Exponenten und einen 2ten Koeffizienten einließt, bist das Eingabeende erreicht wurde (while (eingabeEnde == false)). In der While-Schleife gibt es mehrere Fehlerquellen. So kann z.B. der Exponent = Endzeichen sein, dann wäre natürlich das Eingabeende erreicht (eingabeEnde = true) und natürlich wäre der gesamte Datensatz nicht korrekt eingegeben (falscheEingabe = true). Dieser Fall wäre erreicht, wenn z.B. nach den 2 Grenzen nur noch der Koeffizient eingegeben wird und anschließend das Endzeichen kommt, also KEIN Exponent eingegeben wird (Exponent wird eingelesen, er ist jedoch kein Exponent sondern gleich dem Endzeichen -> Abbruch-Bedingung ist erreicht, eingabeEnde = true z.B.: 2.0 5.0 5 100) Wenn der Exponent != dem Endzeichen ist, dann muss noch geprüft werden, ob der Exponent zwischen den Exponenten-Grenzen ist bzw. dass im Index des Arrays (= an der Stelle des Exponenten) noch keine Daten stehen (sollte dies zutreffen, würde das heißen, dass schon vorher ein gleicher Exponent gelesen wurde und die Daten von diesem Exponenten schon im Array drinnen stehen). Sollte einer dieser Fälle zutreffen ist die Eingabe natürlich falsch (falscheEingabe = true). Nun sind jeweils der erste Koeffizient und der erste Exponent eingelesen (wenn alles glatt gelaufen ist). Deswegen wird nun der nächste Koeffizient eingelesen und dann die While-Schleife neu gestartet. Bevor jedoch der nächste Koeffizient eingelesen wird und mit der While-Schleife weitergemacht wird, muss nochmal eine Überprüfung statt finden: Es darf erst dann der nächste Koeffizient eingelesen werden, wenn der Exponent != dem Endzeichen ist. Würde der Exponent = dem Endzeichen sein würde die Einlesung des nächsten Koeffizienten nichts bringen, da ja das Endzeichen schon erreicht wurde und der "nächste Koeffizient" einfach nichts wäre (leerer Keyboard-Buffer). Der Versuch eben "nichts" aus dem Keyboardpuffer zu lesen, würde in einer Endlosschleife enden. z.B.: 2.0 5.0 5 100 -> Grenzen werden normal bearbeitet, erster Koeffizient 5 wird eingelesen, als Exponent wird 100 eingelesen, dies gibt eine Wenn eben der nächste Koeffizient eingelesen wird (werden kann/werden darf), muss gleich noch überprüft werden, ob dieser nächste Koeffizient != dem Endzeichen ist, damit die While-Schleife korrekt weiterlaufen kann. Sollte jedoch der Koeffizient = dem Endzeichen sein, wird die Eingabe abgebrochen (eingabeEnde = true). z.B.: 2.0 5.0 5 4 100 Nachdem die Eingabe komplett überprüft wurde und die While-Schleife mehr oder minder oft durchgelaufen ist, wird geprüft ob es sich um eine falsche Eingabe (falscheEingabe == true) gehandelt hat oder ob es oben bei der Einlesung des ersten Koeffizienten einen Sofort-Abbruch (sofortEnde == true) gegeben hat. In einen dieser Fälle muss eine Fehlermeldung ausgegeben werden: EprogIO.println("FALSCHE EINGABE") Wenn kein Fehler aufgeetreten ist, wird die Berechnung gestartet. Bevor die ganze Rechnung startet wird noch überprüft, ob die Grenzen eh nicht gleich waren (da das Ergebnis sofort 0 wäre). Sollten die Grenzen nicht gleich sein, beginnt er die Berechnung laut FOrmelt der Angabe. Am Ende der Berechnung ist es noch sehr wichtig, die Daten richtig auszugeben, eben mit 3 Komma-Stellen mit printFixedln(ergebnis). So das wärs eigentlich. Hoffe dir mit meiner ausführlichen Beschreibung geholfen zu haben, sollte es dennoch Probleme geben, schreib mir ein Mail :) Hier am Ende nun nochmal der gesamten Sourcecode jedoch mit komplett allen Kommentaren sowie mit allen Testausgaben: ------------------------ S O U R C E C O D E S T A R T ------------------------ /********************************************** * Beispiel: 1002 - Tantrap * Aufgabe: Zeichen mit Suchbegriff vergleiche * Autor: Martin Pickelbauer * Matrikel-Nummer: 0326586 * Mail: e0326586@student.tuwien.ac.at * Project started: 23.11.2003 * Last edited: 24.11.2003 21:00 * Dokumentation: siehe Tantrap.txt **********************************************/ import eprog.*; public class Tantrap extends EprogIO { //************************ // KONSTANTEN FESTLEGEN * // *********************** public static int ENDZEICHEN = 100; // Zeichen, wo das Einlesen des Ausdruckes abgebrochen wird public static int MIN_EXPONENTEN = 0; // Minimaler Exponent public static int MAX_EXPONENTEN = 8; // Maximaler Exponent public static double TEILINTERVALLBREITE = 0.2; // Grosse des Teilintervalles !!! <- WARUM da double und net float? public static void main(String[] args) { //**************************** // VARIABLEN INITIALISIEREN * // *************************** float uGrenze = 0; // untere Integralgrenze float oGrenze = 0; // obere Integralgrenze float ergebnis; // Gesamtergebnis der Berechnung int koeffizientenEinlesung = 0; // Variable für Koeffizienten-Einlesung, Initialisierung mit 0 int exponent = 0; // Variable für Exponenten-Einlesung, Initialisierung mit 0 boolean gleicheGrenzen = false; // Integralgrenzen chekcen, wenn Grenzen gleich dann true boolean eingabeEnde = false; // zeigt an, ob Eingabe beendet werden soll (da Endzeichen erreicht) boolean falscheEingabe = false; // falscheEingabe = true wenn Fehler im Eingabedatensatz boolean sofortEnde = false; // wenn True, bricht sofort schleife ab int[] koeffizientToExponent = new int[MAX_EXPONENTEN+1]; // Array anlegen, um Koeffizienten den Exponenten (=Array-Indizes) zuzuordnen for (int i=0; i<=MAX_EXPONENTEN; i++) { // Array mit 0 fullen koeffizientToExponent[i] = 0; } //************************** // EINLESEN DES AUSDRUCKES * //************************** try { float grenze1 = readFloat(); // einlesen der ersten Integralgrenze float grenze2 = readFloat(); // einlesen der zweiten Integralgrenzen if (grenze1 != grenze2) { // Uberprufung der Grenzen, wenn Grenzen gleich => Ergebnis=0 oGrenze = Math.max(grenze1,grenze2); // obere bzw. untere Grenze festlegen uGrenze = Math.min(grenze1,grenze2); // obere bzw. untere Grenze festlegen // EprogIO.println("obere grenze: " + oGrenze); // Testausgabe // EprogIO.println("untere grenze: " + uGrenze); // Testausgabe } else { gleicheGrenzen = true; // Wenn die Integralgrenzen gleich sind, ist Ergebnis automatisch 0 und wird unten ausgewertet } koeffizientenEinlesung = readInt(); // Koeffizienten einlesen if (koeffizientenEinlesung == ENDZEICHEN) { // wenne Koeffizient = Endzeichen sofortEnde = true; // sofortiges Ende, da nur Grenzen und Endzeichen } else { // wenne Koeffizient nicht Endzeichen while (eingabeEnde == false) { // so lange Schleife machen, bis ich nicht mehr einlesen soll (eingabeEnde eben true) exponent = readInt(); // Exponenten einlesen if (exponent == ENDZEICHEN) { // wenn jedoch Exponent = Endzeichen, dann eingabeEnde = true; // eingabeEnde = true setzen, damit Einleseschleife beendet wird und falscheEingabe = true; // falscheEingabe = true setzen, da Eingabedaten falsch, da ein Wert zuwenig eingegeben wurde } else { // wenne MIN_EXPONENTEN <= Exponent <= MAX_EXPONENTEN und noch nichts im Array steht an der Stelle Exponent if (exponent >= MIN_EXPONENTEN && exponent <= MAX_EXPONENTEN && koeffizientToExponent[exponent] == 0) { koeffizientToExponent[exponent] = koeffizientenEinlesung; // den Koeffizienten den Array an der Stelle Exponent zuweisen } else { // wenn obige etwas mit Exponent nicht stimmt falscheEingabe = true; // falscheEingabe = true und somit Fehler ausgeben } } // wenn Exponent nicht Endzeichen (im Falle das Exponent = Endzeichen ist, // dann hätte er Koeffizienten wieder einlesen wollen und wäre in Endlosschleife hängen geblieben if (exponent != ENDZEICHEN) { koeffizientenEinlesung = readInt(); // nächsten Koeffizienten einlesen if (koeffizientenEinlesung == ENDZEICHEN) { // wenn Koeffizient = Endzeichen ist, eingabeEnde = true, und somit ende der Einleseschleife eingabeEnde = true; } } } } // Testausgabe // EprogIO.println("sofortEnde :" + sofortEnde + " eingabeEnde: " + eingabeEnde + " falscheEingabe: " + falscheEingabe); if (falscheEingabe == true || sofortEnde == true) { EprogIO.println("FALSCHE EINGABE"); } else { if (gleicheGrenzen == true) { EprogIO.println("0"); } else { // EprogIO.println("wir sind im else und er rechnet"); // Testausgabe // for (int i=0; i<=MAX_EXPONENTEN; i++) { // Testausgabe // if (koeffizientToExponent[i] != 0) { // EprogIO.println("exp: " + i + " koefizient: " + koeffizientToExponent[i]); // } // } /**************************** * BERECHNUNG DES AUSDRUCKES * ****************************/ long n; // Anzahl der Teilintervalle <-- WARUM da float? müsste ja int sein float xk; // Zwischenwert x k float xk_minus_1; // Zwischenwert x k-1 float xk_zwischenWert; // Zwischenwert x k-1 plus x k durch 2 float teilSumme; // Teilsumme float gesamtSumme = 0; // Gesamtsumme der Teilsummen float grenzenDifferenz; // n = (int) Math.round((oGrenze-uGrenze)/TEILINTERVALLBREITE); // Berechnung der Anzahl der Teilintervalle // double m = (oGrenze-uGrenze)/TEILINTERVALLBREITE; // Berechnung der Anzahl der Teilintervalle // println("m-Wert: " + m); // Testausgabe // n = Math.round (m); // println("n-Wert: " + n); // Testausgabe grenzenDifferenz = oGrenze - uGrenze; // Differenz zwischen den Integralgrenzen // Wenn der Unterschied der 2 Grenzen kleiner als die Teilintervallbreite wäre, würde er als Rundungsergebnis 0 bekommen // und würde dann in weiterer Folge durch 0 dividieren, was wiederum auch ein Fehler ist. Darum weise ich n=1 zu, // um mind. 1 Teilintervall zu haben, was mathematisch kein Fehler ist, jedoch die Genauigkeit nicht so genau wird. if (grenzenDifferenz < TEILINTERVALLBREITE) { n = 1; } else { n = Math.round(grenzenDifferenz/TEILINTERVALLBREITE); } for (int k=1; k<=n; k++) { // Berechnung fur jeden Teil von 1 bis n xk_minus_1 = uGrenze + (((oGrenze-uGrenze)/n)*(k-1)); // Berechnung vom Zwischenwert x k-1 // println("xk_minus_1: " + xk_minus_1); // Testausgabe xk = uGrenze + (((oGrenze-uGrenze)/n)*k); // Berechnung vom Zwischenwert x k // println("xk: " + xk); // Testausgabe xk_zwischenWert = (xk_minus_1 + xk)/2; // Berechnung vom Zwischenwert x k-1 plus x k durch 2 // println("xk_zwischenWert: " + xk_zwischenWert); // Testausgabe teilSumme = 0; for (int exp = MIN_EXPONENTEN; exp <= MAX_EXPONENTEN; exp++) { double blub = exp + Math.pow(xk_zwischenWert,exp); // println("math-pow-rechnung: xk_zwischenWert: " + xk_zwischenWert + " exp: " + exp + " blub " + blub); // Testausgabe teilSumme += koeffizientToExponent[exp] * (Math.pow(xk_zwischenWert,exp)); // Summe des einzelnen Array-Elements bilden } gesamtSumme += teilSumme; // Gesamtsumme durch addieren der einzelnen Teilsummen bilden } ergebnis = (oGrenze-uGrenze)/n * gesamtSumme; // Ergebnis berechnen println(ergebnis); // Testausgabe des gesamten Ergebnisses (ohne Abschneiden der Kommastellen) printFixedln(ergebnis); // Ausgabe des Ergebnisses mit 3 Kommastellen } } } catch (EprogException e) { // FEHLERMELDUNG rausschmeissen, wenn Eingabedaten nicht stimmen EprogIO.println("?"); } } }