# Automaten-Applet zur Überprüfung einer Sprache



## MAJA (28. Dez 2009)

Hallo,

in der Schule behandeln wir gerade Automaten. Unsere Lehrerin gab uns die Aufgabe ein Applet zu programmieren, welches einen Automaten als Vorlage hat und überprüfen soll, ob ein Wort in der Sprache des Automaten vorkommt. Teil der Aufgabe war es, uns diesen Automaten selbst auszudenken bzw. die enstsprechende Sprache. 

Wir hatten uns das so gedacht: Der DAU gibt das Wort ein, das Programm überprüft anschließend jeden einzelnen Buchstaben und ob das Wort die Bedingungen der Sprache erfüllt. 

Wir haben vorher schonmal Applets programmiert, aber noch keine die wir in Automaten einbinden sollten. Könnt ihr uns vllt eine grobe Übersicht von Befehlen geben, die oben genanntes Programm ermöglicht oder Denkanstöße für die Lösung unseres Problems?

Hier ein Bild unseres Automaten:


----------



## SlaterB (28. Dez 2009)

Applet oder nicht hat mit dem Problem nix zu tun, ein Applet stellt vielleicht die Ergebnisse graphisch dar und hat nen 'Start'-Knopf,

das Programm an sich ist jedoch Java, da tut es auch erstmal ein Konsolen-Programm mit main-Methode, falls bekannt,
Knoten und Regeln beschreiben, möglichst in eigenen Klassen, ein Netz aufbauen, wer kennt wen,

dann ein Wort Buchstabe für Buchstabe durchgehen, richtig, gibt es Regeln, die weiterführen?
bin jetzt nicht sicher, ob gar mehrere Alternativen zu prüfen sind, Rekursion wäre dann ein Stichwort

bestimmte Befehle braucht man da nicht, außer vielleicht charAt() usw.
was ist der aktuelle Buchstabe? a? 
auf welchem Knoten bin ich gerade, welche Regeln gibt es, passen die zu Buchstaben a?

for-Schleifen, if-Abfragen, einfache Dinge, nur günstig kombiniert


----------



## Meldanor (28. Dez 2009)

1. Der Automat ist unschön gemacht, da es zu "abstürzen" kommen kann, wenn man bei Knoten A z.B. nochmal ein i übergeben wird.
2. Ich habe in der Schule mir ein schönes Konzept ausgearbeitet.

Ich habe als
final int 
die Zustände definiert.
Dann habe ich in einer for Schleife die EIngabe abgearbeitet, indem ich jeden char mir angeschaut habe.
Zuerst bin ich über eine äußere switch Anweisungin den jeweiligen Zustand gesprungen. Dieser Zustand wird als Klassenvariable mitgespeichert und kann nur die Werte annehmen, die bei den Konstanten Definiert ist.
In dieser Switch Anweisung dann folgt bei jedem Zustand eine weitere Switch Anweisung, um die Eingabe zu betrachten.

Also:
Konstanten für die Speicherung des aktuellen Automatenzustandes
Variable, die ständig den ZUstand speichert
per while-Schleife Eingabe abarbeiten, die solange ausgeführt wird, bis ein Endzustand erreicht wurde 
1. Switch Anweisung : Aktuellen Automatenzustand überprüfen
2. Switch Anweisung im jeweiligen Zustand: Aktuelle Eingabe überprüfen

Das habe ich dann auch für Turing Maschinen benutzt und sah sehr sauber aus und war schnell und einfach anzupassen.


----------



## MAJA (5. Jan 2010)

Liebe User,


danke für eure Hilfe soweit. Wir haben jetzt vor, dass das Programm das Wort einliest und für jeden Buchstaben eine Variable setzt. Anschließend wollen wir dann jede Variable mit einer if-Schleife darauf prüfen ob der Buchstabe folgen darf bzw. obs der richtige ist. Allerdings kennen wir keinen Befehl, der uns das ermöglicht. Kennt ihr einen der uns das ermöglichen würde und würdet ihr ihn uns dann mitteilen?

Gruß
MAJA


----------



## Meldanor (5. Jan 2010)

```
Char tempChar = EINGELESENER_STRING.charAt(POSITION);
switch(tempChar){
case 'BUCHSTABE':
tueDas();
break;
case 'ANDERE_BUCHSTABE':
tueDasAndere();
break;
default:
keinErlaubterBuchstabe();
return;
}
```


----------



## MAJA (5. Jan 2010)

Hallo Meldanor,

könntest du uns die Begriffe in rot nochmal erklären, wir haben mit diesen Befehlen noch nicht gearbeitet.


----------



## faetzminator (5. Jan 2010)

Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 2.6 Bedingte Anweisungen oder Fallunterscheidungen


----------



## MAJA (5. Jan 2010)

Wir haben jetzt versucht den Code in unser Programm zu implementieren, jedoch haben wir Probleme den Inhalt des Textfeldes in den switch zu übertragen, dass heißt wir wissen nicht wie wir es dazu bringen unser Textfeld einzulesen. 

Also genau da: Char tempChar = EINGELESENER_STRING.charAt(POSITION);

Was hat das "Position" zu bedeuten?
Und können wir bei " EINGELESENER_STRING" den Namen unseres Textfeldes eintippen und es wird dann eingelesen?


----------



## faetzminator (5. Jan 2010)

per [c]String content = [textFeldName].getText()[/c] o.ä. kommt ihr an den Text ran. Nanach müsst ihr mit einer [c]for[/c]-Schleife über jeden Buchstaben des Strings iterieren. Wenn ihr die Position in der Variable [c]i[/c] speichert, könnt ihr den aktuellen Buchstaben mit [c]char temp = content.charAt(i);[/c] holen.


----------



## MAJA (5. Jan 2010)

Wenn wir das so benutzen, sucht er eigentlich einfach nur das ganze Wort nach dem Buchstaben ab? Wir brauchen das ja so, dass er schaut ob speziell das "i" an erster Stelle steht bzw. das ist dann bei den anderen Buchstaben auch wichtig, dass er das wirklich Buchstabe für Buchstabe nacheinander einliest.


----------



## MAJA (5. Jan 2010)

Also wir haben uns das so gedacht: 


```
public void button1ActionPerformed(ActionEvent evt) {
           for ( y=0; y<0; y++) {
            String content = textField1.getText();
            if (Stringbuchstabe_1="i") {
             Überprüfe Stringbuchstabe_2
              if (Stringbuchstabe_2=4||Stringbuchstabe_2=k)
               Überprüfe Stringbuchstabe_3

            }
            
           }

          }
```

Wie kann man das verwirklichen? Also was wäre der Befehl für "Überprüfe Stringbuchstabe_x" und für if (Stringbuchstabe_x ...)?


----------



## SlaterB (5. Jan 2010)

-->


faetzminator hat gesagt.:


> könnt ihr den aktuellen Buchstaben mit [c]char temp = content.charAt(i);[/c] holen.


<---

i ist hier der Index, man kann auch 0, 1, 2, .. einsetzen


----------



## faetzminator (5. Jan 2010)

SlaterB, du siehst aber schon, dass sie eine "rekursive Methode" nicht rekursiv verwirklichen wollen  ?
Nein, macht pro Knoten eine Methode, welche den String im korrekten Fall mit if/else oder switch an die nächste korrekte weitergibt oder ansonsten eine Exception schmeisst - oder du verwendest return Codes.


----------



## MAJA (7. Jan 2010)

Faetzminator,

könntest du uns vielleicht einen Beispielcode geben, wir wissen nicht so wirklich was damit anzufangen.


----------



## MAJA (7. Jan 2010)

Also wir sind jetzt so weit:


```
public void button1ActionPerformed(ActionEvent evt) {
           String content = textField1.getText();
           char tempChar = content.charAt(0);
                switch(tempChar){
                case 'i':
                label1.setText( "Win" );
                break;
                case 'f':
                label1.setText("Ihr Wort ist nicht Teil der Srpache");
                break;

                }
          }
```

Unser Problem jetzt: Wie können wir anstatt case 'f' etwas wie "alles andere außer i" hinschreiben? 
Und nochwas: bei einer if-Schleife kann man ja per "||" eine oder-Bedingung festlegen, gibt es sowas für den case Befehl?


----------



## faetzminator (7. Jan 2010)

MAJA hat gesagt.:


> Unser Problem jetzt: Wie können wir anstatt case 'f' etwas wie "alles andere außer i" hinschreiben?


Mit [c]default:[/c].


MAJA hat gesagt.:


> Und nochwas: bei einer if-Schleife kann man ja per "||" eine oder-Bedingung festlegen, gibt es sowas für den case Befehl?


Nein.

Ein Beispiel kann ich vielleicht etwas später liefern.


----------



## MAJA (7. Jan 2010)

Also wir haben das jetzt folgendermaßen gelöst:


```
char tempChar5 = content.charAt(5);
                switch(tempChar5){
                case 'r':
                case 'j':
                case 'w':
                case 'o':
                case '8':
                label1.setText("Ihr Wort ist nicht Teil der Sprache");
                label1.setBackground(Color.RED);
                break;
                case 'n':
                label1.setText( "Ihr Wort ist Teil der Sprache" );
                label1.setBackground(Color.GREEN);
                break;
                default :
                label1.setText("Ihr Wort ist nicht Teil der Sprache");
                label1.setBackground(Color.RED);
                break;

                }
```

Es läuft zwar soweit, jedoch haben wir da ein Problem:
Bei "i4on" zeigt er an, dass es Teil der Sprache sei. Da vor einem "n" allerdings eine "8" stehen müsste ist dies aber nicht richtig, hat jemand eine Idee wie man das in eine Bedingung bringen könnte?


----------



## SlaterB (7. Jan 2010)

derartige Bedingungen prüften man mit einem Automaten, mit Zuständen und Regeln,

charAt hilft nur um den char zu bestimmen, aber was genau an Position 5 alles erlaubt ist oder nicht
hängt doch vom aktuellen Zustand im komplexen System eines Automaten ab, abhängig von den vorherigen Zeichen,

das einfach wegzulassen funktioniert nicht


----------



## MAJA (7. Jan 2010)

Das heißt jetz so viel wie: Das geht so gar nich und wir können alles übern haufen werfen?


----------



## SlaterB (7. Jan 2010)

das heißt, dass 20 Zeilen das Problem nicht lösen, auch wenn sie für sich nicht falsch sind,
ab 200 Zeilen wirds vielleicht interessant

man fängt an das erste Zeichen zu lesen,
was am Anfang erlaubt ist, ist noch leicht, falsche Zeichen können aussortiert werden,
aber wenn es mehrere erlaubte Regeln gibt, dann kann das Programm danach in zwei oder mehr verschiedene Zustände landen,
das mit if/ else zu behandeln ist nicht zu schaffen, denn in jeder von potentiell tausenden Stufen kommen neue Unterscheidungen dazu,
ganz simplel ist dagegen, sich den neuen Zustand zu merken, bin ich bei Knoten A oder C oder sonstwo,
dann den nächsten Buchstaben und abhängig vom aktuellen Zustand A oder C oder sonstwo verschiedene Buchstaben akzeptieren

das ganze muss in einer Schleife laufen, allgemeinen Code ständig wiederholen,
für Zeichen i speziellen Code zu schreiben bringt nichts, selbst das erste Zeichen kommt in den allgemeinen Ablauf mit rein,
deshalb Objekte definieren, Regeln von X nach Y,

am Anfang hat man nur vier Informationen: das Wort, Index 0 im Wort, den Startzustand + das ganze System als Netzwerk modelliert


edit:
ok, statt Klassen für die Regeln und Knoten zu definieren kann es auch bei einfachen Variablen und switch bleiben, ist nur aufwendig:

```
int zustand = ..
char c = ..

if (zustang == ..) {
  switch (c) {
      // akzeptieren und neuen Zustand setzen oder abbrechen
   } 
} else if (zustand == ..) {
   switch (c) {
   ..
} else ..
```


----------

