arithmetische Ausdrücke prüfen

sh

Aktives Mitglied
In einer fiktiven Programmiersprache gibt es arithmetische Ausdrücke wie in der Mathematik, z.B. 2 + 3. Zur Vereinfachung gibt es nur „Fully Parenthesized Expressions“ (FPE), d.h. dass jeder Operator mit seinen beiden Operanden geklammert ist. Priorität und Assoziativität sind hier irrelevant. Numerale sind zur Vereinfachung nur einzelne Dezimalziffern ohne Vorzeichen.
Korrekte FPEs sind z.B. (2 + ( 3 * 4)) oder ((2 + 3 ) * 4)
Unzulässige FPEs wären: 2 + 3 * 5 oder (2+ ) * 5 oder )(
Ihre Aufgabe ist es, einen als String gegebenen Ausdruck auf syntaktische Korrektheit hin zu untersuchen, d.h. Sie müssen zuerst überprüfen, ob die Klammern im String korrekt geschachtelt sind. Ihre Methode liefert entsprechend true oder false.

Auf den ersten Blick sieht das garnicht so schwer aus, aber wenn man sichs dann mal genauer überlegt.. Um 100%ige Korrektheit zu überprüfen muss man schon einiges beachten. Zunächst hab ich gedacht "Regexp und gut is!" aber stellt sich heraus das ein Regex für so eine Syntax überprüfung garnicht so leicht ist.

Also gehn wirs mal langsam an, hier meine erste Methode:
Code:
	public boolean isBalanced(String fpe) {
		char[] chars = fpe.toCharArray();
		int opened = 0, closed = 0;
		for(char c : chars) {
			if(c == '(')
				opened++;
			if(c == ')')
				closed++;
		}
		return opened > 0 && opened == closed;
	}
Was die macht is klar, einfach nur sehen ob genau so viele offene Klammern '(' wie geschlossene Klammern ')' in der FPE sind. Auch muss mindestens eine Klammer offen (dh. auch geschlossen) sein, da '5 + 2' keine FPE ist.

Nur wie überprüfe ich die restliche syntaktische Korrektheit?
Nach jeder offenen Klammer muss ja entweder eine Zahl mit Operator oder eben eine neue FPE kommen.

Jede Hilfe für (möglichst) schlaue Lösungsansätze ist willkommen!

MfG

EDIT:
Ich vermute stark das die Aufgabe auf eine Rekursion hinausläuft.
 
Zuletzt bearbeitet von einem Moderator:

Ariol

Top Contributor
Deine Methode ist leider falsch:

Java:
	public boolean isBalanced(String fpe) {
				
		//Alle Leerzeichen aus fpe entfernen
		char[] chars = fpe.toCharArray();
		int opened = 0;
		boolean isFPE = false;
		char previousChar=' ';
		for(char c : chars) {
			if(c == '(') {
				//PseudoCode:
				if(prevoiusChar.isNumber) //"3(" ???
					return false;		
				isFPE=true;
				opened++;
			}
			else if(c == ')')
			{
				//PseudoCode:
				if(prevoiusChar.isOperator)
					return false; // "+)" ???
				opened--;
			}
			else
			{
				//PseudoCode:
				if(prevoiusChar.isOperator && c.isOperator) // "++"???
					return false;	
				//etc....
			}				
			previousChar=c;

			if(opened<0) {
				return false; //Schließende Klammer vor öffnender Klammer
			}
		}
		return isFPE && opened != 0; //Alle Klammern geschlossen
	}
 
Zuletzt bearbeitet:

sh

Aktives Mitglied
Mhh ich denke nicht das meine isBalanced() falsch ist, die Methode ansich soll ja nur sehen ob es
a) exakt soviele '(' wie ')' gibt und
b) mindestens eine '(' bzw ')' gibt

Deine Methode macht doch eigentlich das gleiche, nur das du die "Klammerntiefe" bei '(' hochzählst und bei ')' runterzählst.

Hab gerade beide getestet und sehe da keinen Unterschied. Das eigentliche Problem, ob die Klammern (Ausdrücke) korrekt geschachtelt sind muss man natürlich anders lösen (ich vermute mit einer Rekursion).

EDIT:
Grade geposted da hast du editiert ;)
 

Blakh

Bekanntes Mitglied
Java:
return isFPE && opened != 0; //Alle Klammern geschlossen

Muss das nicht opened == 0 sein?
 

pexx

Mitglied
@sh: die aufgabe hatte ich auch mal so ähnlich. eine einfache lösung war die indizes der öffnenden (is) und schließenden klammern (ie) zu suchen. wenn weder is noch ie da sind, balanced. wenn nur einer der indizes existiert, unbalanced. wenn beide indizes existieren, rekursion mit dem substring von is+1 bis ie .

die methode prüft natuerlich nur die klammern, nicht jedoch die operatoren oder operanden.

EDIT: habs gefunden

Java:
public static boolean isBalanced (String t) {
		
		int s = t.indexOf('('); 
		int e = t.lastIndexOf(')');
		
		if ((s == -1) && (e == -1))
			return true;
		else if ((s == -1) || (e == -1) || (s >= e))
			return false;
		else
			return isBalanced(t.substring(s+1, e));	
	}
 
Zuletzt bearbeitet:

sh

Aktives Mitglied
Ich denke ich weiss nun wie es geht. In der Teilaufgabe c) (ja die habe ich euch verschwiegen, hab ich grad aus den Tiefen meines Ordners hervorgekramt) ist eine Zustandstabelle. Einfach dumm nach der Tabelle programmieren sollte klappen. Mein zweiter Lösungsansatz war eh schon relativ ähnlich.

Code:
package aufgabe1;

public class FPE {
	
	public static void main(String... args) {
	
		
	}
	
	private enum State {
		OpenBracket, Digit, Operator, CloseBracket, Eof, Undefined
	}
	
	private boolean isCorrectSyntax(String fpe) {
		CHECK check = new CHECK(fpe);
		//...... do the check stuff here
	}
	
	private static class CHECK {
		private char[] fpe;
		private int pos;
		
		public CHECK(String fpe) {
			this.fpe = fpe.toCharArray();
			pos = -1;
		}
		
		public State nextState() {
			pos++;
			if(fpe.length - 1 < pos)
				return State.Eof;
			if(fpe[pos] == ' ')
				return nextState();
			if(fpe[pos] == '(')
				return State.OpenBracket;
			if(fpe[pos] == ')')
				return State.CloseBracket;
			if(Character.isDigit(fpe[pos]))
				return State.Digit;
			if(fpe[pos] == '+' || fpe[pos] == '*')
				return State.Operator;
			return State.Undefined;
		}
		
	}
	

	
}

Das Mal grob wie ichs angegangen bin, hier noch wie der Automat dazu aussieht:
l4qb5lkp.png


EDIT:
Okay, ich komm mit der Zustandstabelle schon nicht klar. Wieso kann im Zustand "Plain" ein Operator kommen (1. Zeile, letzte Spalte).
Also im Zustand "Plain" wird eine OpenBracket erkannt. Ist noch nachvollziehbar, das erste Zeichen muss ja '(' sein. Nur wieso geht man, wenn im Zustand "Plain" ein Operator kommt dann zu Numeral1?
Ich mein, dann wär ja zB. ein + oder * am ANFANG der FPE?
Bzw. weiß jemand wie das Ding korrekt auszufüllen ist?

EDIT2:
Stimmt das so?
kvl8uyss.png


EDIT3:
Hier mal meine Lösung nach obiger Zustandstabelle, könnte mir bitte jemand sagen ob das so richtig ist?
Code:
package aufgabe1;

public class FPESyntax {
	
	public static void main(String... args) {
		
		String fpe = "((1+2)*(3+4))";
		System.out.println(isCorrectSyntax(fpe));
		
	}
	
	private static boolean isCorrectSyntax(String fpe) {
		
		//eventuell noch whitespaces strippen
		char[] chars = fpe.toCharArray();
		
		int depth = 0;
		
		State state = State.Plain;
		
		for(int i = 0; i < chars.length; i++) {
			if(state == State.Plain) {
				if(chars[i] == '(') {
					depth++;
					state = State.OpenBracket;
				} 
				else if(chars[i] == '+' || chars[i] == '*') {
					state = State.Numeral1;
				}
				else if(chars[i] == ')' || Character.isDigit(chars[i])) {
					return false;
				}
			}
			else if(state == State.OpenBracket) {
				if(isOpenBracket(chars[i])) {
					depth++;
					state = State.OpenBracket;
				}
				else if(isClosedBracket(chars[i])) {
					return false;
				}
				else if(isDigit(chars[i])) {
					state = State.Numeral1;
				}
				else if(isOperator(chars[i])) {
					return false;
				}	
			} 
			else if(state == State.Numeral1) {
				if(isOpenBracket(chars[i]) || isClosedBracket(chars[i]) || isDigit(chars[i])) {
					return false;
				}
				else if(isOperator(chars[i])) {
					state = State.Operator;
				}
			}
			else if(state == State.Numeral2) {
				if(isOpenBracket(chars[i]) || isDigit(chars[i]) || isOperator(chars[i])) {
					return false;
				}
				else if(isClosedBracket(chars[i])) {
					depth--;
					state = State.CloseBracket;
				}
			}
			else if(state == State.Operator) {
				if(isOpenBracket(chars[i])) {
					depth++;
					state = State.OpenBracket;
				}
				else if(isClosedBracket(chars[i]) || isOperator(chars[i])) {
					return false;
				}
				else if(isDigit(chars[i])) {
					state = State.Numeral2;
				}
			}
			else if(state == State.CloseBracket) {
				if(isOpenBracket(chars[i]) || isDigit(chars[i])) {
					return false;
				}
				else if(isClosedBracket(chars[i])) {
					depth--;
					state = State.CloseBracket;
				}
				else if(isOperator(chars[i])) {
					state = State.Plain;
				}
			}
		}
		
		if(!isBalanced(fpe))
			return false;
		
		return true;
	}
	
	public static boolean isDigit(char c) {
		return Character.isDigit(c) == true;
	}
	
	public static boolean isOperator(char c) {
		return c == '+' || c == '*';
	}
	
	public static boolean isOpenBracket(char c) {
		return c == '(';
	}
	
	public static boolean isClosedBracket(char c) {
		return c == ')';
	}
	
	public static boolean isBalanced(String fpe) {
		char[] chars = fpe.toCharArray();
		int opened = 0, closed = 0;
		for(char c : chars) {
			if(c == '(')
				opened++;
			if(c == ')')
				closed++;
		}
		return opened > 0 && opened == closed;
	}

	public enum State {
		Plain, OpenBracket, Numeral1, Numeral2, Operator, CloseBracket
	}
	
}
Was ich nach wievor nicht verstehe ist der Zustand "Plain", wieso da ein Operator kommen darf. Ist mit "Plain" ein whitespace-char gemeint?
EDIT-AGAIN(!):
Scheinbar nicht, das Programm funktioniert auch mit whitespaces im FPE, auch wenn man diese nicht strippt. Ich gehe mal davon aus das diese Lösung korrekt ist, wenn jemand noch Anmerkungen hat das ich was falsch gemacht habe, bitte bescheid geben!

In der Aufgabe heißt es ja auch:
Achtung: der Automat erkennt nicht alle Ausdrücke richtig. Er gnügt aber für Ausdrücke der Form
((1+2) * (3+4))


Daraus schließe ich mal das mein Programm trotz Akzeptanz von zB "((1+2) * (3+4))-" dennoch richtig ist.
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
C arithmetische Ausdrücke Java Basics - Anfänger-Themen 7
J Division ohne Arithmetische Funktion Java Basics - Anfänger-Themen 2
S Arithmetische Operatoren Java Basics - Anfänger-Themen 7
M Aufgabe Arithmetische Operatoren Java Basics - Anfänger-Themen 12
M Arithmetische Operatoren Java Basics - Anfänger-Themen 40
S Prüfungsvorbereitung Januar ( Thema Ausdrücke ) Java Basics - Anfänger-Themen 14
B Regex Ausdrücke für Monate Java Basics - Anfänger-Themen 7
W Reguläre Ausdrücke Java Basics - Anfänger-Themen 1
W Reguläre Ausdrücke Java Basics - Anfänger-Themen 1
C Boolsche Ausdrücke Java Basics - Anfänger-Themen 3
schredder Strings und reguläre Ausdrücke - Methode mit return string.matches Java Basics - Anfänger-Themen 5
A Schleifen und Boolsche Ausdrücke Java Basics - Anfänger-Themen 42
G Java Lambda Ausdrücke Java Basics - Anfänger-Themen 19
A Lambda-Ausdrücke Java Basics - Anfänger-Themen 6
K FYI: Reguläre Ausdrücke nutzen ja/nein Java Basics - Anfänger-Themen 2
G Lambda Ausdrücke Java Basics - Anfänger-Themen 2
O Lambda Ausdrücke in einem Comparator Java Basics - Anfänger-Themen 4
B Erste Schritte Boolesche Ausdrücke & Gesetze Java Basics - Anfänger-Themen 3
B Reguläre Ausdrücke Java Basics - Anfänger-Themen 2
S Lambda Ausdrücke Streams Java Basics - Anfänger-Themen 6
D Variablen Ausdrücke Java Basics - Anfänger-Themen 6
P Reguläre Ausdrücke und Korrektheit Java Basics - Anfänger-Themen 2
0 Reguläre Ausdrücke bzw. Zahlenformat im String Java Basics - Anfänger-Themen 7
M Lambda - Ausdrücke verstehen Java Basics - Anfänger-Themen 2
G Reguläre Ausdrücke Zeichenketten Java Basics - Anfänger-Themen 12
C Klassen Reguläre Ausdrücke auf Gleichheit prüfen Java Basics - Anfänger-Themen 5
J Reguläre Ausdrücke Java Basics - Anfänger-Themen 3
C Reguläre-Ausdrücke Java Basics - Anfänger-Themen 5
N Lambda Ausdrücke richtig schreiben Java Basics - Anfänger-Themen 4
F Methoden Lambda Ausdrücke Methodensignatur Java Basics - Anfänger-Themen 6
P Ausdrücke berechnen Java Basics - Anfänger-Themen 2
J Java 8 Lamda ausdrücke Java Basics - Anfänger-Themen 9
J reguläre Ausdrücke Java Basics - Anfänger-Themen 1
C Lambda Ausdrücke Java Basics - Anfänger-Themen 1
B Reguläre Ausdrücke Java Basics - Anfänger-Themen 3
B Java - Reguläre Ausdrücke - RegEx oder Regular Expressions - Eckige Klammern Java Basics - Anfänger-Themen 2
H Erste Schritte Von jpg zu jpeg // reguläre Ausdrücke Java Basics - Anfänger-Themen 3
TheSorm Java 8 Lambda-Ausdrücke Java Basics - Anfänger-Themen 9
K Reguläre Ausdrücke Java Basics - Anfänger-Themen 3
K Reguläre Ausdrücke Java Basics - Anfänger-Themen 6
S Anweisungen Ausdrücke Java Basics - Anfänger-Themen 7
J Regex Ausdrücke im Array - Wieso werden sie nicht erkannt? Java Basics - Anfänger-Themen 4
K Ausdrücke auswerten Java Basics - Anfänger-Themen 8
B Reguläre Ausdrücke Java Basics - Anfänger-Themen 5
C Boolsche Ausdrücke - Wo ist mein Fehler? Java Basics - Anfänger-Themen 14
K Reguläre Ausdrücke Java Basics - Anfänger-Themen 5
M Boolsche Ausdrücke minimieren Java Basics - Anfänger-Themen 13
C Reguläre Ausdrücke: string.matches() und gefangene Gruppen Java Basics - Anfänger-Themen 12
S Reguläre Ausdrücke richtig einsetzten Java Basics - Anfänger-Themen 5
T Reguläre Ausdrücke Java Basics - Anfänger-Themen 18
0 Reguläre Ausdrücke und Funktionen Java Basics - Anfänger-Themen 2
S Datentypen Operatoren und Ausdrücke (formel richtig rechnen) Java Basics - Anfänger-Themen 8
D Reguläre Ausdrücke Java Basics - Anfänger-Themen 3
S Reguläre Ausdrücke Java Basics - Anfänger-Themen 16
A Reguläre Ausdrücke Frage Java Basics - Anfänger-Themen 3
E Reguläre Ausdrücke mit sehr variablen Eigenschaften Java Basics - Anfänger-Themen 2
T Ausdrucksparser für Mathematische Ausdrücke Java Basics - Anfänger-Themen 15
N Ausdrücke Java Basics - Anfänger-Themen 6
N Reguläre Ausdrücke - bekomme Suchkriterium nicht hin Java Basics - Anfänger-Themen 3
J Reguläre Ausdrücke in Java Java Basics - Anfänger-Themen 2
J Reguläre Ausdrücke Java Basics - Anfänger-Themen 6
W Suche nach strings zwischen eckigen Klammern mittels regulärer Ausdrücke Java Basics - Anfänger-Themen 3
S Strings und reguläre Ausdrücke Java Basics - Anfänger-Themen 2
N Reguläre Ausdrücke Java Basics - Anfänger-Themen 4
S Reguläre Ausdrücke Java Basics - Anfänger-Themen 2
M Reguläre ausdrücke? Java Basics - Anfänger-Themen 8
D Reguläre Ausdrücke: Anzahl Wiederholungen als Variable? Java Basics - Anfänger-Themen 3
A Reguläre Ausdrücke Java Basics - Anfänger-Themen 2
M Reguläre Ausdrücke - maskieren von Zeichen? Java Basics - Anfänger-Themen 9
M regüläre Ausdrücke, die String - Variablen und Expression Java Basics - Anfänger-Themen 5
M Reguläre Ausdrücke und Ausgabe Java Basics - Anfänger-Themen 10
K Reguläre Ausdrücke - Gefundene Tokens direkt ermitteln Java Basics - Anfänger-Themen 3
J Reguläre Ausdrücke: Zeichenfolge ausschließen Java Basics - Anfänger-Themen 2
G Reguläre Ausdrücke Java Basics - Anfänger-Themen 13
L java und reguläre ausdrücke Java Basics - Anfänger-Themen 4
G Reguläre Ausdrücke zum Filtern von logfiles Java Basics - Anfänger-Themen 2
T Reguläre Ausdrücke? Java Basics - Anfänger-Themen 3
E Reguläre Ausdrücke Java Basics - Anfänger-Themen 17
O reguläre Ausdrücke bei java.util.regex.Pattern Java Basics - Anfänger-Themen 4
A Reguläre Ausdrücke der Pfade unter Windows und Unix Java Basics - Anfänger-Themen 3
M Ausdrücke -> Werte Java Basics - Anfänger-Themen 6
N Reguläre Ausdrücke Java Basics - Anfänger-Themen 5
G Problem reguläre Ausdrücke Java Basics - Anfänger-Themen 4
A Reguläre Ausdrücke: Inhalt zwischen zwei Schlüsselwörtern Java Basics - Anfänger-Themen 2
A Reguläre Ausdrücke: Problem mit Backslash Java Basics - Anfänger-Themen 3
A mehrere Ausdrücke in for schleife vergleichen Java Basics - Anfänger-Themen 6
D Wie kann man in Java nach Arrays auf Duplikate prüfen Java Basics - Anfänger-Themen 12
J Schlüsselworte Prüfen, ob ein bestimmtes, ganzes Wort in einem String enthalten ist. Java Basics - Anfänger-Themen 6
Ostkreuz Int Scanner auf Enter Eingabe prüfen Java Basics - Anfänger-Themen 4
S Prüfen ob ein zweidimensionales Array rechteckig ist Java Basics - Anfänger-Themen 4
M Prüfen on eine Zahl im String enthalten ist Java Basics - Anfänger-Themen 3
ravenz Schleife mit for über String Array „zahlen“und prüfen ob Wert „a“ oder „b“ oder „c“ entspricht (mittels || ) Java Basics - Anfänger-Themen 4
Fiedelbambu Prüfen von Komma stelle beim Taschenrechner Java Basics - Anfänger-Themen 5
sserio Prüfen, ob eine Zahl eine periodische Zahl ist Java Basics - Anfänger-Themen 20
I Auf vollen Monat prüfen? Java Basics - Anfänger-Themen 22
A Dateiname auf Vorkommen prüfen Java Basics - Anfänger-Themen 29
I Prüfen, ob Anzahl an Monate ein Jahr ergeben Java Basics - Anfänger-Themen 4
K Warum gibt mir z. B. 40^128 eine Zahl? Ich dachte mit xor kann man nur booleanwerte erhalten, also prüfen ob etwas whar oder falsch ist? Java Basics - Anfänger-Themen 1
W Klasse existiert prüfen Java Basics - Anfänger-Themen 5
Q Prüfen ob Zahl als Summe von Potenzen dargestellt werden kann. Java Basics - Anfänger-Themen 20

Ähnliche Java Themen

Neue Themen


Oben