"We are back" « oc.at

Endlicher Automat

SeVen 07.11.2015 - 11:17 7449 45 Thread rating
Posts

Obermotz

Fünfzylindernazi
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
Also meine DFSM kommt mit vier States aus. Dadurch koenntest du dein Programm stark vereinfachen.

automaton_208638.jpg

// es reichen sogar drei States. Du kannst p3 entfernen, p1 zu deinem Finite State machen und von p2 zu p1 traversieren, wenn wieder 0-9 kommt..
Bearbeitet von Obermotz am 08.11.2015, 01:40

SeVen

Little Overclocker
Registered: Apr 2006
Location: Germany
Posts: 96
Aber ich muss auch ein Vorzeichen einsetzten können, also z.B. +3,345 oder -33,123 oder 5678,1. Dann brauche ich doch auch den Zustand Vorzeichen?!
Muss ich nun meine Zustände erstmal alle am Anfang initialisieren damit ich mit dem Vergleich anfangen kann? Und wie kann ich die Werte einzeln aus dem Eingabearray und meinem Zustandsarray vergleichen? Ein ganz kleines Beispiel wäre für mich sehr hilfreich, stehe total auf dem Schlauch...

SeVen

Little Overclocker
Registered: Apr 2006
Location: Germany
Posts: 96
Ich verzweifel gerade total. Kann ich so anfangen:
Code:
int[][] Zustaende = { {1,4,2},//1. Spalte = V, 2. Spalte = K, 3. Spalte = Z 
                           {4,4,2},
                           {2,3,2},
                           {4,4,5},
                           {4,4,4},
                           {4,4,5} }


     int s = 0;
     char[] zeile; char c;
     zeile = IO.readChars( "Bitte geben Sie eine Kommazahl ein: ");
     int i;
     c = zeile [i];

       for( i = 0; i < zeile.length; i++){
         c = zeile[i];
           if( c == '+' || '-' ){
   
  }
}

SeVen

Little Overclocker
Registered: Apr 2006
Location: Germany
Posts: 96
Ich habe mir nochmals eine neue Tabelle erstellt um es zu minimieren.
Wie kann ich nun die eigebenen Zeichen einzeln vergleichen?

tinker

SQUEAK
Avatar
Registered: Nov 2005
Location: NÖ
Posts: 5249
@Obermotz: Wie SeVen schon gesagt hat, fehlt bei dir das Vorzeichen. Und das weglassen von p3 wird nicht funktionieren, weil der Automat dann beliebig viele Kommazeichen akzeptieren würde. Und bei p3 fehlt noch eine Schleife mit 0-9, sonst kann die Zahl nur eine Nachkommastelle haben.

@SeVen: Die neue Tabelle schaut gut aus, so hab ichs auch.

Zu deinem letzten Code: die Zeile "c = zeile [i];" direkt vor der for-Schleife macht so keinen Sinn, vor allem weil die Variable i nicht initialisiert wurde. Was du im Endeffekt machen musst (ohne Zustandsarray und nur mit einer Variable): Mach eine Variable zustand die du vor der Schleife mit 0 initialisierst. Und eine int Variable eingabe die du ebenfalls mit 0 initialisierst. Die beiden Variablen wirst du verwenden um auf deine Übergangstabelle zuzugreifen.

In der Schleife holst du dir zuerst das aktuelle Zeichen, das machst du eh schon. Dann kommt dein if-else-Konstrukt wo du abfragst um welches Zeichen es sich handelt. Je nachdem um welche Art von Zeichen es sich handelt, weist du der Variable eingabe einen anderen Wert zu (Vorzeichen = 0, Komma = 1, Zahl = 2).

Und jetzt musst du die Variable zustand nur noch mit dem neuen Zustand aus der Übergangstabelle initialisieren. Den richtigen Wert bekommst du dabei durch die beiden Variablen zustand und eingabe, die zu diesem Zeitpunkt ja schon richtig initialisiert sind.

Danach geht die Schleife weiter. Nach dem Durchlaufen der gesamten Schleife überprüfst du dann ob die Variable zustand den Wert eines Endzustands hat.
Bearbeitet von tinker am 08.11.2015, 11:23

SeVen

Little Overclocker
Registered: Apr 2006
Location: Germany
Posts: 96
Das klingt schon sehr gut!
Ich habe nun folgendes:

Code:
char[] zeile; 
     zeile = IO.readChars( "Bitte geben Sie eine Kommazahl ein: ");
     int i;
     int Zustand = 0;
     int Eingabe = 0;

       for( i = 0; i < zeile.length; i++){
         if( zeile [i] == '+' || '-' ){
           Eingabe = 0;
         }
         else if( zeile[i] == ',' ){
           Eingabe = 1;
         }
         else if( zeile[i] >= 48 && zeile[i] <= 57 ){
           Eingabe = 2;
         }
         else{
         IO.println( "Die Eingabe ist ungueltig!");
         }
   
         Zustand =

Wie kann ich denn nun die Variable Zustand mit dem neuen Zustand aus der Übergangstabelle initialisieren?

tinker

SQUEAK
Avatar
Registered: Nov 2005
Location: NÖ
Posts: 5249
Zitat von SeVen
Wie kann ich denn nun die Variable Zustand mit dem neuen Zustand aus der Übergangstabelle initialisieren?
ok, da schau dir an wie man auf (mehrdimensionale) arrays zugreift, is jetzt nicht so schwer ;)

und " zeile [i] == '+' || '-' " wird so auch nicht funktionieren.

und das mit dem "IO.println( "Die Eingabe ist ungueltig!");" im else is auch nicht so schön. Wenn die Eingabe vom User zb. "aabbccdd" ist, dann wird 8 mal "Die Eingabe ist ungueltig!" ausgegeben. Also entweder ersetzt du die for-Schleife durch ne andere und brichst gleich ab, wenn ein Fehler passiert, oder du definierst in der Übergangstabelle noch eine Eingabeart "ungültig" die immer in den Fehlerzustand wechselt.

SeVen

Little Overclocker
Registered: Apr 2006
Location: Germany
Posts: 96
kann ich dann ein Variable char c initialisieren und dann dann schreiben:
c = zeile[i];

und damit c == '+' || '-' ?

Blaues U-boot

blupp, blupp
Avatar
Registered: Aug 2005
Location: Graz
Posts: 1542
nachfolgender ausdruck wird wohl sein was du meinst:
(zeile[i] == '+') || (zeile[i] == '-')

bei logikausdrücken gibt es klammerregeln und priorisierte operationen vergleichbar zu mathematischen ausdrücken (*/ vor +- usw.). schau dir das am besten mal an. braucht man immer bei komplexeren bedingungen.

Obermotz

Fünfzylindernazi
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
Darf ich fragen, wo man Automatentheorie lernt, ohne vorher Soft1 zu machen?

@tinker: Man kennt, dass ich schon ein paar Bier intus hatte gestern :D

SeVen

Little Overclocker
Registered: Apr 2006
Location: Germany
Posts: 96
Code:
int[][] Zustaende = { {1,4,2},//1. Spalte = V, 2. Spalte = K, 3. Spalte = Z 
                           {4,4,2},
                           {2,3,2},
                           {4,4,5},
                           {4,4,4},
                           {4,4,5} }


     char[] zeile;
     zeile = IO.readChars( "Bitte geben Sie eine Kommazahl ein: ");
     int i;
     int Zustand = 0;
     int Eingabe = 0;

       for( i = 0; i < zeile.length; i++){
         if(( zeile [i] == '+' ) || ( zeile[i] == '-' ){
           Eingabe = 0;
         }
         else if( zeile[i] == ',' ){
           Eingabe = 1;
         }
         else if( zeile[i] >= 48 && zeile[i] <= 57 ){
           Eingabe = 2;
         }
         else{
           Eingabe = 3;
         }

         Zustand = 

Jetzt muss ich doch dafür Sorgen, dass der Zustand = 1 wird, wenn beispielsweise ein Vorzeichen eingegeben wurde. Also muss Zustand = bei Eingabe = 0 (Vorzeichen) im Array Zustaende dem Wert [0] [0] zugeordnet werden, richtig?

SeVen

Little Overclocker
Registered: Apr 2006
Location: Germany
Posts: 96
So in der Richtung eventuell? Vielen Dank schoneinmal für die schnelle Hilfe. So langsam wird es etwas klarer.
Code:
char[] zeile;
     zeile = IO.readChars( "Bitte geben Sie eine Kommazahl ein: ");
     int i;
     int Zustand = 0;
     int Eingabe = 0;

       for( i = 0; i < zeile.length; i++){
         if(( zeile [i] == '+' ) || ( zeile[i] == '-' ){
           Eingabe = 0;
         }
         else if( zeile[i] == ',' ){
           Eingabe = 1;
         }
         else if( zeile[i] >= 48 && zeile[i] <= 57 ){
           Eingabe = 2;
         }
         else{
           Eingabe = 3;
         }

         new int[] Zustandar;
         Zustandar[i] = Eingabe;

SeVen

Little Overclocker
Registered: Apr 2006
Location: Germany
Posts: 96
Nun kann ich printen ob es eine Zahl ist oder auch kein Zahl. Ich weiß nicht wie ich den Zustand Kommazahl noch reinbekommen soll :-(
Hat dazu noch irgendjemand einen Tipp?

Code:
char[] zeile;
     zeile = IO.readChars( "Bitte geben Sie eine Kommazahl ein: ");
     int i;
     int Zustand = 0;
     int Eingabe = 0;

       for( i = 0; i < zeile.length; i++){
         if(( zeile[i] == '+' ) || ( zeile[i] == '-' )){
           Eingabe = 0;
         }
         else if( zeile[i] == ',' ){
           Eingabe = 1;
         }
         else if( zeile[i] >= 48 && zeile[i] <= 57 ){
           Eingabe = 2;
         }
         else{
           Eingabe = 3;
         }

         int[] Zustandar;
         Zustandar = new int [zeile.length];
         Zustandar[i] = Eingabe;
       }
       if( Eingabe == 2 ){
         IO.println( " Zahl");
         }
       else{ IO.println ("keine Zahl");}
 }
}

Denne

Here to stay
Avatar
Registered: Jan 2005
Location: Germany
Posts: 2801
Ich bin ungern der Spielverderber, aber dein Automat funzt vorne und hinten nicht, da er auch Zahlen mit mehreren '+', '-' und ',' erkennt und die Reihenfolge, in welcher sie vorkommen, keine Rolle spielen. Er dürfte z.B. auch "9,14+,-,76,2" als Kommazahl erkennen, wenn ich mich nicht irre.

So wie ich es auf den ersten Blick sehe, ist nur wichtig, was das letzte char in deinem input ist. Sobald es eine Zahl ist, wird Eingabe 2 und er erkennt es als Zahl an. Alles was vor dem letzten char ist spielt absolut keine Rolle, so wie du es aktuell hast.
Bearbeitet von Denne am 08.11.2015, 18:09

schizo

Produkt der Gesellschaft
Avatar
Registered: Feb 2003
Location: Vienna
Posts: 2566
Hier hast du ein gültiges Zustandsdiagramm (insofern ich deine Angabe richtig verstanden habe):
click to enlarge

Startzustand ist 1, gültige Endzustände 3 und 5
Du musst im Grunde nur schauen, dass die Zustände nur inkrementiert werden können (bzw. bei 3&5 nicht dekrementiert werden können) und du bei Zustand 3/5 die Eingabe beenden kannst.
Bei Zustand 3 handelt es sich um keine Kommazahl, bei Zustand 5 um eine Kommazahl.
Bearbeitet von schizo am 08.11.2015, 18:43
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz