Die Grenzen ergeben sich abhängig von den verwendeten Typen für die
Variablen. Werden deren Wertebereiche (Bsp. int von -2147483648 bis +2147483647)
bei der Eingabe überschritten, tritt eine Java-Exception auf. Diese werden
allerdings in den Methoden der Klasse IO abgefangen und es wird ein Wert 0 an
das rufende Prg. zurückgeg.
Ein Sonderfall wäre die Eingabe nicht numerischer Zeichen. Auch in diesem
Fall tritt eine Java-Exception auf, welche ebenfalls in den Methoden der Klasse
IO abgefangen wird, wobei wieder der Wert 0 an das rufende Prg zurückgegeben
wird. .
Eingabewerte: 15, 30, -1
Erwartete Ausgabe: Größter Wert (biggest) = 30, Zweitgrößter
Wert (secondBiggest) = 15
Zweck: Test, ob die Ermittlung von größtem und zweitgrößtem
Wert richtig funktioniert.
Eingabewerte: 200, 100, 300, -100
Erwartete Ausgabe: Größter Wert (biggest) = 300, Zweitgrößter
Wert (secondBiggest) = 200
Zweck: Test, ob die Ermittlung von größtem und zweitgrößtem
Wert richtig funktioniert.
Eingabewerte: 50, -2
Erwartete Ausgabe: Fehlermeldung, weil nur eine positive Zahl eingeg. wurde
Zweck: Test, ob Fehlerfall - wenn weniger als zwei Zahlen eingeg. werden - richtig
behandelt wird.
Eingabewerte: A
Erwartete Ausgabe: Keine, da nicht numerische Eingabe.
Zweck: Test eines Sonderfalls.
A | B | C | D | E | C | D | E | |
---|---|---|---|---|---|---|---|---|
number | null | 15 | 15 | 15 | 30 | 30 | 30 | -1 |
counter | 0 | 0 | 1 | 1 | 1 | 2 | 2 | 2 |
biggest | 0 | 0 | 0 | 15 | 15 | 15 | 30 | 30 |
secondBiggest | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Glücklicherweise hat dieser vollführte Schreibtischtest ergeben, dass mein Algorithmus aus Übung 1 dummerweise einen Fehler beinhaltet. Wird die größte Zahl erkannt, muss natürlich die zweitgrößte Zahl den ursprünglichen Wert der größten Zahl erhalten.
Die Grenzen ergeben sich durch den Datentyp int, dieser ist 32 Bit groß
und hat einen Wertebereich von -2147483648 bis +2147483647. Wird dieser Bereich
bei der Eingabe überschritten, tritt eine Java-Exception auf. Diese werden
allerdings in den Methoden der Klasse IO abgefangen und es wird ein Wert 0 an
das rufende Prg. zurückgeg.
Ein Sonderfall wäre die Eingabe nicht numerischer Zeichen. Auch in diesem
Fall tritt eine Java-Exception auf, welche ebenfalls in den Methoden der Klasse
IO abgefangen wird. Auch in diesem Fall wird der Wert 0 an das rufende Prg.
zurückgeg.
Ein weiterer Sonderfall wäre die Eingabe von negativen Zahlen, da diese
in der Aufgabenstellung und auch im Algorithmus unberücksichtigt geblieben
sind.
Noch ein Sonderfall wäre die Eingabe von rationalen Zahlen, da der Algorithmus
nur ganze Zahlen berücksichtigt.
Eingabewerte: 2 / 11 / 127
Erwartete Ausgabe: 2^1 / 11^1 / 127^1
Zweck: Test, ob die Ermittlung der Primfaktoren von 1- bis 3-stelligen Primzahlen
richtig funktioniert.
Eingabewerte: 78
Erwartete Ausgabe: 2^1 * 3^1 * 13^1
Zweck: Test, ob die Ermittlung der Primfaktoren ganzer Zahlen richtig funktioniert.
Eingabewerte: 13332
Erwartete Ausgabe: 2^2 * 3^1 * 11^1 * 101^1
Zweck: Test, ob die Ermittlung der Primfaktoren größerer ganzer Zahlen
richtig funktioniert.
Eingabewerte: -11
Erwartete Ausgabe: Keine, da negative Zahlen im Algorithmus nicht berücksichtigt
wurden.
Zweck: Test des Sonderfalles negativer Zahlen.
Eingabewerte: A
Erwartete Ausgabe: Keine, da nicht numerischer Wert.
Zweck: Test des Sonderfalles nicht numerischer Werte.
A | B | C | D | E | F | C | D | E | F | |
---|---|---|---|---|---|---|---|---|---|---|
Zahl (number) | 78 | 78 | 78 | 78 | 39 | 39 | 39 | 39 | 13 | 13 |
Faktor (factor) | - | - | 2 | 2 | 2 | 2 | 3 | 3 | 3 | 3 |
Häufigkeit (factor_count) | - | - | - | 0 | 0 | 1 | - | 0 | 0 | 1 |
Primfaktoren-String (strFactors) | null | "" | "" | "" | "" | "2^1" | "2^1" | "2^1" | "2^1" | "2^1 * 3^1" |
C | F | C | F | ... | C | F | |
---|---|---|---|---|---|---|---|
Zahl (number) | 13 | 13 | 13 | 13 | ... | 13 | 13 |
Faktor (factor) | 4 | 4 | 5 | 5 | ... | 12 | 12 |
Häufigkeit (factor_count) | - | 0 | - | 0 | ... | - | 0 |
Primfaktoren-String (strFactors) | "2^1 * 3^1" | "2^1 * 3^1" | "2^1 * 3^1" | "2^1 * 3^1" | ... | "2^1 * 3^1" | "2^1 * 3^1" |
C | D | E | F | G | |
---|---|---|---|---|---|
Zahl (number) | 13 | 13 | 1 | 1 | 0 |
Faktor (factor) | 13 | 13 | 13 | 13 | 13 |
Häufigkeit (factor_count) | - | 0 | 0 | 1 | 1 |
Primfaktoren-String (strFactors) | "2^1 * 3^1" | "2^1 * 3^1" | "2^1 * 3^1" | "2^1 * 3^1 * 13^1" | "2^1 * 3^1 * 13^1" |
Der gegebene Satz "BACBBACACBBACBAB" lässt sich aus folgenden Grammatiken ableiten:
Um im Algorithmus immer zu wissen, welcher Teil der Syntax gerade geprüft
werden muss, wird eine Variable syntax_branch
verwendet,
welche den aktuellen zu prüfenden Syntax-Zweig beinhaltet. Dafür werden
den verschiedenen Zweigen der Syntax einfach ganzzahlige Werte zugewiesen:
"B" "A" { "C" [ "B" ["B" ] ] "A" }"B"
1 2 3 4 5 6 7 8
8 stellt das erwartete Ende der Zeichenkette dar. Kommt bei der Prüfung
im Zweig 8 noch ein Zeichen, ist die geprüfte Zeichenkette ungültig.
Um die Regeln der versch. Syntax-Zweige abzubilden, bietet sich die switch
-Anweisung
an.
Die Prüfung der Zeichenkette wird in einer Funktion checkSyntax(String
word)
vom Typ boolean
vorgenommen. Dieser Methode wird eine
Zeichenkette übergeben, welche mit Hilfe der Methode IO.readWord()
gelesen wird.
Um den Test des Prg. zu erleichtern, werden die Zeichenketten in einer Schleife gelesen (um mehrere Zeichenketten prüfen zu können) und die Eingabe des Wortes "END" als Abbruchbedingung definiert.
/** * * Softwareentwicklung I - Exercise 2/2. * Check EBNF syntax "BA"{"C"["B"["B"]]"A"}"B" on a String read from Input. * * @author Daniel Brunthaler (0255054) * @version 1.0 * */ public class Parser { /** * Checks EBNF syntax "BA"{"C"["B"["B"]]"A"}"B" on given word. * * @param word which should be checked. * @return true if given word comply with EBNF syntax. */ static boolean checkSyntax(String word) { /** * The branch of the syntax which has * to be checked on a certain character. * * The given EBNF syntax is divided in branches as follows: * * "B""A"{"C"["B"["B"]]"A"}"B" * 1 2 3 4 5 6 7 8 * * branch 8 stands for expected end of the word. */ int syntax_branch = 1; int wordLength = word.length(); // length of the word char symbol; // certain symbol out of the word for (int i = 0;i < wordLength;i++) { // check character for character from given word symbol = word.charAt(i); switch (syntax_branch) { case 1: if (symbol == 'B') syntax_branch = 2; else return false; break; case 2: if (symbol == 'A') syntax_branch = 3; else return false; break; case 3: if (symbol == 'C') syntax_branch = 4; else if (symbol == 'B') syntax_branch = 8; else return false; break; case 4: if (symbol == 'B') syntax_branch = 5; else if (symbol == 'A') syntax_branch = 7; else return false; break; case 5: if (symbol == 'B') syntax_branch = 6; else if (symbol == 'A') syntax_branch = 7; else return false; break; case 6: if (symbol == 'A') syntax_branch = 7; else return false; break; case 7: if (symbol == 'B') syntax_branch = 8; else if (symbol == 'C') syntax_branch = 4; else return false; break; case 8: return false; } } if (syntax_branch == 8) { // all characters in the word checked, end of syntax reached return true; } else { return false; } } public static void main(String[] args) { String word = IO.readWord(); while (!word.equals("END")) { if (checkSyntax(word)) { IO.writeLn("Given word is VALID!"); } else { IO.writeLn("Given word is NOT valid!"); } word = IO.readWord(); } System.exit(0); } }
Da diesmal ein String vom Input eingelesen wird, sind die möglichen Sonderfälle
stark beschränkt. Ein Sonderfall wäre hierbei wohl, wenn kein einziges
Zeichen eingeg., nur die Enter-Taste betätigt wird. Auch die Grenzen sind
bei diesem Algorithmus nur Hardware-abhängig, wobei es äußerst
unwahrscheinlich ist, dass eine größere Zeichenkette eingeg. wird,
als der Speicher der ausführenden Hardware verträgt.
Somit werden einige gültige und ungültige Zeichenketten getestet und
der Sonderfall, dass kein Zeichen eingeg. wird.
Eingabe: BA
Erwartete Ausgabe: Ungültige Zeichenkette
Zweck: Test, ob Algorithmus funktioniert.
Eingabe: BACBBABA
Erwartete Ausgabe: Ungültige Zeichenkette
Zweck: Test, ob Algorithmus funktioniert (Zeichenkette bis zum vorletzten Buchstaben
gültig)
Eingabe: BACAB
Erwartete Ausgabe: Gültige Zeichenkette
Zweck: Test, ob Algorithmus funktioniert (Kleinste gültige Zeichenkette)
Eingabe: BACBAB, BACBBAB
Erwartete Ausgabe: Bei beiden gültige Zeichenkette
Zweck: Test, ob Algorithmus funktioniert
Eingabe: BACACBACBBACBACAB
Erwartete Ausgabe: Gültige Zeichenkette
Zweck: Test, ob Algorithmus funktioniert (mehrere Durchläufe des Zweiges
"C"["B"["B"]]"A")
Eingabe: [Enter]
Erwartete Ausgabe: Keine, da IO.readWord()
diese Eingabe ignoriert
Zweck: Test des Sonderfalles, wenn kein Zeichen eingeg. wird