Aufgabe 1

Algorithmus "Größte Werte"

Ablaufdiagramm

Entnommen aus meiner 1. Übung und ergänzt um Positions-Bezeichnungen.

Grenzen und Sonderfälle

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. .

Testplan

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.

Schreibtischtest

  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.

Algorithmus "Primfaktoren"

Ablaufdiagramm

Entnommen aus meiner 1. Übung und ergänzt um Positions-Bezeichnungen.

Grenzen und Sonderfälle

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.

Testplan

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.

Schreibtischtest

  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"

Aufgabe 2

Grammatiken

Der gegebene Satz "BACBBACACBBACBAB" lässt sich aus folgenden Grammatiken ableiten:

Lösungsidee

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.

Source

/**
 * 
 * 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);
    }
}

  

Test

Testplan

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

Hardcopy