Wohlgeformtheit eines Ausdrucks

DerChris1992

Mitglied
Hallo,

Aufgabe ist folgende gewesen;

Arithmetische Ausdrücke. Wir betrachten nun sehr einfache arithmetische Ausdrücke. Erlaubtsind Klammern, die binären Operatoren „+“, „-“, “*“, “/“, sowie Zahlen mit einer einzelnen Ziffer(„0“,“1“,...,“9“). Erlaubt wäre also z.B.: „1+2+3“ oder „(1+2)*3+(4-7)“. Verboten wären dagegen„23+42“, „-4“ (unäres Minus erlauben wir nicht) oder „2++“, und natürlich auch falsche Klammerungenwie „((3+2)“. Leere Klammern machen auch keinen Sinn: „()+4“ ist verboten.Schreiben Sie ein JAVA Programm, das kontrolliert, ob ein eingegebener String das richtigeFormat hat (also nur geklammerte Ausdrücke von den vier Grundrechenarten mit Zahlen dieaus einzelnen Ziffern bestehen).



Java:
public class Doityourself_b {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
                
                String Bracket_open=new String ("(2+(2*(3-5)"); //String erstellen 
                char [] open=Bracket_open.toCharArray(); // In Char umwandeln, um jedes Zeichen lesen zu können
                
                if(open[0] == '(' && open[1] == '1'||open[1] == '2'||open[1] == '3'||open[1] == '4'||open[1] == '5'||open[1] == '6'||open[1] == '7'||open[1] == '8'||open[1] == '9'){
                    
                    for(int i=2;i < Bracket_open.length();i++) {
                        try {
                            if(open[i] == '+'||open[i] == '-'||open[i] == '*'||open[i] == '/') {
                            
                                if(open[i+1] == '1'||open[i+1] == '2'||open[i+1] == '3'||open[i+1] == '4'||open[i+1] == '5'||open[i+1] == '6'||open[i+1] == '7'||open[i+1] == '8'||open[i+1] == '9') {
                        
                                    if(open[i+2] == ')') { 
                                        i=i+2;
                                        continue;
                                    }
                                }
                                else if(open[i+1] == '(') 
                                
                                    if(open[i+2] == '1'||open[i+2] == '2'||open[i+2] == '3'||open[i+2] == '4'||open[i+2] == '5'||open[i+2] == '6'||open[i+2] == '7'||open[i+2] == '8'||open[i+2] == '9') {
                                        i=i+2;
                                        continue;
                                    }
                                    else
                                        System.out.println("Der Ausdruck entspricht nicht dem richtigen Format");
                                        System.exit(0);
                                }
                            
                            else                             
                                System.out.println("Der Ausdruck entspricht nicht dem richtigen Format");
                                System.exit(0);    
                                } catch (ArrayIndexOutOfBoundsException e) {
                                    System.out.println("Der Ausdruck entspricht nicht dem richtigen Format");
                                    System.exit(0);
                                 
                            }
                        
                                
                             
                    }
                    System.out.println("Der Ausdruck entspricht dem richtigen Format");
                    
                }
                    else                            
                        System.out.println("Der Ausdruck entspricht nicht dem richtigen Format");
                        System.exit(0);    
                 
    }


}
 
Zuletzt bearbeitet:
@TE: Was du da hast ist ein riesen Berg spaghetti-code. Nimm eine Regular Expression (Tutorial) dafür, da passt das alles in 2-3 Zielen und ist vieeel leichter erweiterbar.
Es ist aber zu erwarten, dass ihr den Ausdruck auch irgendwann ausrechnen sollt. Um dafür gewappnet zu sein, kannst du dir den Shunting-Yard-Algorithmus ansehen, mit welchem sich beliebige arithmethische Ausdrücke berechnen. Das hat auch dern Vorteil, dass du dabei direkt das Format validierst.
 
@TE: Was du da hast ist ein riesen Berg spaghetti-code. Nimm eine Regular Expression (Tutorial) dafür, da passt das alles in 2-3 Zielen und ist vieeel leichter erweiterbar.
Es ist aber zu erwarten, dass ihr den Ausdruck auch irgendwann ausrechnen sollt. Um dafür gewappnet zu sein, kannst du dir den Shunting-Yard-Algorithmus ansehen, mit welchem sich beliebige arithmethische Ausdrücke berechnen. Das hat auch dern Vorteil, dass du dabei direkt das Format validierst.


Danke erstmal.

Dazu habe ich eine Kleine Frage:

Java:
import java.util.regex.Pattern;public class Doityourself_b {


	public static void main(String[] args) {
		// TODO Auto-generated method stub
				
				String Input=new String ("(2");
				
				if(Input.matches("[(]+[0-9]+[+.-.*./]"))
					System.out.println("erlaubt");
				else
					System.err.println("nicht erlaubt");
				 	
			


	}


}

Wenn ich da + - * und / definiere, wie kann ich die trennen? Weil mit dem Punkt klappt das Programm zwar, aber auch eine Eingabe (2. wäree erlaubt.

Danke!
 
Du musst die Rechenzeichen escapen:
Java:
if(Input.matches("[(]+[0-9]+[\\+\\-\\*\\/]"))
					System.out.println("erlaubt");
Allerdings sind so immer noch Ausdrücke wie:

(1+

erlaubt. Also ganz so einfach ist es nicht. Vor allem könnte es schwieriger sein, für jede öffnende Klammer wieder eine schließende zu haben etc. Da könnte dir die lookahead assertion vllt helfen ;P
 
Ich bin voll überfordert 🙁

Also so rein systematisch, ist der Anfang doch immer gleich also (Zahl Rechenoperation Das kann ich also schon mal voraussetzen und dann muss ich doch eine Schleife machen, weil ich ja nicht weiß, wie lang mein String ist. Und das kann ich in einer Schleife abfangen,

Aber wie sage ich, dass in meinem Array die 4 Stelle (3. stelle im Array) entweder eine Zahl oder eine Klammer auf sein muss? ..

also (2+( oder (2+3 zum Beispiel
 
Ok, ich kenn zwei recht einfache Methoden, es zu lösen. Allerdings will ich jetzt nicht beide hier aufschreiben. Deshalb frage ich mal zunächst, ob du weißt, was Rekursion ist. Damit wäre es nämlich deutlich einfacher. Wenn nicht, erkläre ich dir die normale iterative Methode.

lg Kevin
 
Ok, das machts etwas einfacher. Du erstellst also eine Methode 'boolean checkExpression(String exp)', die true zurück gibt, wenn 'exp' ein gültiger Ausdruck (Expression) ist. Jetzt musst du nur noch definieren, was ein Expression ist:
- Der String ist nur eine Zahl, dann gebe true zurück
- (siehe unten) Der String ist ein Klammerausdruck, sieht also so aus: '(' + exp + ')' und exp ist wieder ein Expression. Du prüfst also, ob das erste Zeichen '(' und das letzte Zeichen ')' ist, dann nimmst du den Substring ohne die Klammern (Stichwort: exp.substring(...)) und prüfst ob dieser ein gültiger Ausdruck ist.
- Ansonsten suchst du den nächsten Operator, indem du durch den String iterierst. Dabei musst du aber die öffnenden und schließenden Klammern zählen. Also du hast eine Variable 'klammern', zählst sie hoch, wenn du eine öffnende Klammer siehst, und bei einer schließenden eins runter. Wenn du ein Operator gefunden hast UND 'klammern' gleich 0 ist, also in keinem Klammerausdruck bist, teilst du den String in zwei Teile, und prüfst ob diese beiden Teile gültige Ausdrücke sind.
- Wenn du in der Schleife keinen Operator findest, ist der Ausdruck nicht gültig. Du kannst dabei auch prüfen, ob 'klammern' irgendwann negativ wird, aber dieser Fall wird eh schon abgefangen.

lg Kevin

PS: übrigens du kannst mit "if (c >= '0' && c <= '9')" prüfen, ob ein Zeichen eine Ziffer ist, da die Ascii-Codes der Ziffern 0 bis 9 fortlaufend sind, also zwischen 48 ('0') und 57 ('9').
PSS: Ah mist, ein kleiner Denkfehler! Den rot markierten Text machst du am Ende. Du suchst also ein Operator, der nicht in einem Klammerausdruck steht. Wenn du keinen gefunden hast, prüfst du erst dann, ob der String ein Klammerausdruck ist, also ob das erste Zeichen '(' und das letzte Zeichen ')' ist. Sonst würde er beim String '(1+2)*(3+4)' den String erst zereißen '1+2)*(3+4'
 
Zuletzt bearbeitet:

Zurück
Oben