Wohlgeformte Klammern

Hero

Mitglied
Hallo Leute,

Ich hab angefangen Java zu lernen und ich hab in Internet eine schöne Aufgabe gefunden, nämlich:
Ich soll Klammern auf wohlgeformt überprüfen. Gemeint ist ob die Klammern in richtiger Reihenfolge sind

Bsp von einer Wohlgeformten Klammer-Kombination:
Code:
{ ( [ ] ) }

Bsp von einer Nicht-Wohlgeformten Klammer-Kombination
Code:
{ ( [ ) ] }

Ich hab mir überlegt gehabt jede Klammer eine Zahl zu geben > []=1,-1 < und dann die Zahlen zu addieren: 1+(-1)=0

Die Frage ist jetzt wie man einen Char eine Zahl zu teilen kann bzw. ist es überhaupt möglich dann so eine Rechenoperation durch zu führen?
 

HoaX

Top Contributor
Mit Zahlen addieren wirst du nicht weit kommen. Aber um dich in die richtige Richtung zu stupsen: verwende einen Stack
 

Hero

Mitglied
Hallo,
Danke erstmal für die Schnelle Antwort.
Ich hab mir die Funktion von Stack durchgelesen und Beispiele angeguckt aber ich versteh jetzt nicht wie man den String "{ ( [ ] ) }" bzw. "{ ( [ ) ] }" auf Korrektheit überprüfen kann.
 

langhaar!

Bekanntes Mitglied
Wenn du eine offene Klammer findest, packst du sie auf den Stack.
Wenn du eine geschlossene Klammer findest, siehst du dir die letze offene Klammer an; diese musst du im Stack gespeichert haben.
Sind die Klammern verschieden, so hast du einen Klammerfehler gefunden.
Sind die Klammern gleich, nimmst du die offene Klammer vom Stack.
Auf deinem Stack sind somit nur offene Klammern und deine obige Frage stellt sich gar nicht,

EDIT:
Wenn dein Klammerprogramm z.B. die KLammergültigkeit von Java-Code erkennen soll, so musst du noch Kommentare berücksichtigen; dort sind die Klammern zu ignorieren.
 
Zuletzt bearbeitet:

Hero

Mitglied
Also ich bin jetzt soweit, dass das Programm alle offenen Klammern in den Stack packt aber ich weiß jetzt nicht wie z.B.:"{" und "}" vergleichen soll. Es sind doch eigentlich zwei unterschiedliche Zeichen.
 

Hero

Mitglied
Ich vergleiche die die Klammern als char (charAt) aber muss sie als String in den Stack packen als Char ging das nicht.

Java:
public class wohlKlammern 
{
		static void check (String str, Stack stack) {
		
			while(true){
				try {
					for(int i=0;i<str.length();i++){
						if(str.charAt(i)=='}' ^ str.charAt(i)==')' ^ str.charAt(i)==']'){
							System.out.println(stack.pop());
						}
					}
		         } catch (EmptyStackException e) {
		            break;
		         }
			}
			
		}

		public static void main(String[] args) {
			
			BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
			System.out.println("Bitte geben Sie einen Klammerausdruck ein:");
			
				try {
					String strg= input.readLine();
					
					Stack<String> s=new Stack<String>();
					for(int i=0;i<strg.length();i++){
						
						if(strg.charAt(i)=='{' ^ strg.charAt(i)=='(' ^ strg.charAt(i)=='['){
							
							s.push(strg.substring(i,i+1));
							
						}
					}
					
					check(strg,s);
					return;
					
				} catch (IOException e) {
					System.out.println(System.err);
					
					e.printStackTrace();
				}			
		}
	}
 

Marco13

Top Contributor
In Worten: Du musst alle ÖFFNENDEN Klammern auf den Stack pushen, und immer, wenn du eine SCHLIESSENDE Klammer findest, schauen, ob oben auf dem Stack die dazu passende (!) offene Klammer liegt, und wenn ja, dann diese Offene Klammer wegnehmen...
 

Hero

Mitglied
Also wenn ich eine Klammer-Kombination eingeben wie "{ ( [ ] ) }", werden "{ ( [" auf dem Stack gepusht, die Frage die ich mir schon die ganze Zeit stelle ist sage ich dem Programm, das "[" und "]" zusammen passen.
 
B

bygones

Gast
dieses "mapping" musst du im programm haben, d.h. dein programm weiss, dass wenn "]" kommt es nach "[" schauen muss, zb ueber eine Map
Java:
Map<String,String> klammern = new HashMap<String,String>();
klammern.put("]","[");
klammern.put(")","(");
klammern.put("}","{");
 

langhaar!

Bekanntes Mitglied
Hast du die Aufgabe wirklich im Internet gefunden oder ist es vielleicht doch eine Übungs/Hausaufgabe?

Ist letzteres der Fall, dann sollst du vermutlich eine rekursive Lösung erarbeiten und keinen Stack verwenden.
 

Landei

Top Contributor
Eine Variante ohne Stack:

Java:
public class Bracket {
    private final char closing;
    private final Bracket parent;

    public Bracket(char closing, Bracket parent) {
        this.closing = closing;
        this.parent = parent;
    }

    public Bracket add(char c) {
        if (c == closing) {
            return parent;
        }
        switch (c) {
            case '(': return new Bracket(')', this);
            case '[': return new Bracket(']', this);
            case '{': return new Bracket('}', this);
            default: return null;
        }
    }

    public static boolean process(String s){
        final Bracket start = new Bracket('X',null);
        Bracket current = start;
        for(int i = 0; i< s.length(); i++) {
            current = current.add(s.charAt(i));
            if(current == null) {
                return false;
            }
        }
        return (current == start);
    }

    public static void main(String[] args) {
        //ein paar Tests
        System.out.println(process("([]{})"));
        System.out.println(process("([]{}"));
        System.out.println(process("([{]})"));
    }
}
 

HoaX

Top Contributor
Da finde ich das aber einfacher zu lesen und verstehen:
Java:
import java.util.Stack;

public class Klammern {

	static void parse(char[] s) throws Exception {
		Stack<Integer> klammern = new Stack<Integer>();
		
		for(int i=0; i<s.length; i++) {
			switch(s[i]) {
			case '{': klammern.push((int)'}'); break;
			case '[': klammern.push((int)']'); break;
			case '(': klammern.push((int)')'); break;
			default:
				if (s[i] != klammern.pop())
					throw new Exception("Falsche Klammer!");
			}
		}
	}
	
	public static void main(String[] args) throws Exception {
		String s = "([{]})";
		parse(s.toCharArray());
		System.out.println("ok");
	}
	
}
 

langhaar!

Bekanntes Mitglied
@Landei
Schon klar, aber wenn du sagst, du hast eine Lösung ohne Stack, dann gehe ich davon aus, dass du konzeptionell etwas ganz anderes gemacht hast (z.B. Rekursion) und nicht, dass du einen Stack unter anderem Namen implementierst.

Da wir jetzt schon zwei Lösungen haben, werd ich morgen mal zum Vergleich die rekursive Variante ergänzen.
 
Zuletzt bearbeitet:

Landei

Top Contributor
OK, für alle Nörgler hier noch eine "wirklich" stackfreie Lösung:

Java:
    public static boolean process(String s) {
        if (s.isEmpty()) return true;
        int index = s.indexOf("()");
        if (index == -1) index = s.indexOf("[]");
        if (index == -1) index = s.indexOf("{}");
        if(index == -1) return false;
        String s1 = s.substring(0, index);
        String s2 = s.substring(index + 2,s.length());
        return process(s1 + s2);
    }
 

tfa

Top Contributor
Und für die Supernörgler eine echt wirklich stackfreie Lösung:
Java:
public static boolean process(String s) {
	while (!s.isEmpty()) {
        String s2=s;
		s2 = s2.replaceAll("\\(\\)", "");
		s2 = s2.replaceAll("\\[\\]", "");
		s2 = s2.replaceAll("\\{\\}", "");
		if (s.equals(s2)) {
			return false;
		}
		s = s2;
	}
	return true;
}
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Mal nebenbei: Ich weiß nicht, ob es "klug" ist, davon auszugehen, dass der ganze String immer NUR aus Klammern besteht.... ???:L Aber wenn's nur eine Uni-Aufgabe ist, kann das ja sogar sein ;)
 

Landei

Top Contributor
Mal nebenbei: Ich weiß nicht, ob es "klug" ist, davon auszugehen, dass der ganze String immer NUR aus Klammern besteht.... ???:L Aber wenn's nur eine Uni-Aufgabe ist, kann das ja sogar sein ;)

Na ja, man kann auch alles andere per RegEx rauswerfen. Und wenn das auch ausgewertet werden soll, steckt man ja schon mitten in "richtigem" Lexer-Parser-Geraffel.
 

Marco13

Top Contributor
Naja... kompliziertes Lexer/Parser "Geraffel" braucht man nur, wenn man noch verschiedene Arten von
/* Kommentaren
// Wie z.B. diesem */
verstehen will, ansonsten ist es
Code:
for (i=0 bis length) {
    if charAt(i) ist KlammerAuf { push(k); }
    else if charAt(i) ist KlammerZu { prüfeUndPoppe(); }
}
Zugegeben, auch nicht praxisnah, aber doch praxisnäher als zu versuchen, Quellcode mit RegEx zu bearbeiten :D
 

Gossi

Bekanntes Mitglied
Oder sowas ^^

Java:
import java.util.ArrayList;
import java.util.List;

public class BracketResolve {

	List<String> openBrackets = new ArrayList<String>();

	public boolean inputIsOk(final String input) {
		for (char c : input.toCharArray()) {
			if (c == 40) {
				openBrackets.add("(");
			}
			if (c == 91) {
				openBrackets.add("[");
			}
			if (c == 123) {
				openBrackets.add("{");
			}
			if (c == 41) {
				if (openBrackets.get(openBrackets.size() - 1).toCharArray()[0] == (c - 1)) {
					openBrackets.remove(openBrackets.size() - 1);
				} else {
					return false;
				}
			}
			if (c == 93) {
				if (openBrackets.get(openBrackets.size() - 1).toCharArray()[0] == (c - 2)) {
					openBrackets.remove(openBrackets.size() - 1);
				} else {
					return false;
				}
			}
			if (c == 125) {
				if (openBrackets.get(openBrackets.size() - 1).toCharArray()[0] == (c - 2)) {
					openBrackets.remove(openBrackets.size() - 1);
				} else {
					return false;
				}
			}
		}
		return true;
	}

	public boolean inputIsOk(final List<String> input) {
		String complet = "";
		for (String string : input) {
			complet = complet + string;
		}
		return inputIsOk(complet);

	}

	public boolean inputIsOk(final char[] input) {
		String complet = input.toString();
		return inputIsOk(complet);
	}

}

Die Klasse hab ich am Anfang der Ausbildung mal geschrieben....
 

HoaX

Top Contributor
@gossy: Ein Char mit einem Zahlenwert zu vergleichen ist böse, da braucht man ja ne Ascii-Tabelle neben sich um zu wissen wann da was passieren soll.
 

Marco13

Top Contributor
Ich gehe davon aus, dass das als "mahnendes Beispiel" gedacht war, im Sinne von: "Es ist mir zwar jetzt ein bißchen peinlich, aber Die Klasse hab ich am Anfang der Ausbildung mal geschrieben" ... ;)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Stacks wohlgeformte Klammerausdrücke Java Basics - Anfänger-Themen 14
O Java Kara geschweifte Klammern Java Basics - Anfänger-Themen 2
M Klasse in Runden Klammern bei Objektimplementierung Java Basics - Anfänger-Themen 4
J Eckige Klammern werden nicht erkannt Java Basics - Anfänger-Themen 1
J Klammern werden fälschlicherweise eingelesen Java Basics - Anfänger-Themen 2
T split innerhalb Klammern ignorieren? Java Basics - Anfänger-Themen 6
S Java Text splitten mit Tabs, Zeilen, Zeichen und Klammern. Java Basics - Anfänger-Themen 6
D Werte in eckige Klammern finden Java Basics - Anfänger-Themen 3
D Compiler-Fehler kurze Frage (Fehler): runde Klammern im Println Java Basics - Anfänger-Themen 3
B Java - Reguläre Ausdrücke - RegEx oder Regular Expressions - Eckige Klammern Java Basics - Anfänger-Themen 2
F while Schleife ohne Klammern Java Basics - Anfänger-Themen 9
N enum vergleiche Klammern? Java Basics - Anfänger-Themen 5
K Erste Schritte Geschweifte Klammern Java Basics - Anfänger-Themen 12
H Nur Zahlen, Klammern und Operatoren Java Basics - Anfänger-Themen 3
R alleinstehende geschweifte Klammern Java Basics - Anfänger-Themen 5
M keine geschwungenen Klammern Java Basics - Anfänger-Themen 9
B Text zwischen geschweiften klammern Java Basics - Anfänger-Themen 11
B bestimmte klammern im string ersetzten Java Basics - Anfänger-Themen 17
B Klammern im String Java Basics - Anfänger-Themen 9
T Syntax für .split mit Klammern Java Basics - Anfänger-Themen 2
E Regex für geschweifte Klammern? Java Basics - Anfänger-Themen 10
StrikeTom Per regex string zwischen klammern raussuchen Java Basics - Anfänger-Themen 14
Luk10 Wo zum Teufel fehlen Hier Klammern? Java Basics - Anfänger-Themen 2
K println - Klammern von Operationen Java Basics - Anfänger-Themen 4
W Suche nach strings zwischen eckigen Klammern mittels regulärer Ausdrücke Java Basics - Anfänger-Themen 3
D Klammern in regulären Ausdrücken Java Basics - Anfänger-Themen 2
C Klammern einlesen!!! Falsche Ausgabe!!!! Java Basics - Anfänger-Themen 4
Developer_X Problem mit Klammern im Code Java Basics - Anfänger-Themen 17
Daniel_L Geschweifte Klammern nutzen oder nicht? Java Basics - Anfänger-Themen 3
M Wie ersetzt man einen String mit eckigen Klammern Java Basics - Anfänger-Themen 5
E Irgendwo fehlen Klammern ? Java Basics - Anfänger-Themen 6
B Was steht innerhalb von solchen <.> Klammern Java Basics - Anfänger-Themen 2
H Klammern bei replaceAll-Methode Java Basics - Anfänger-Themen 3
W Problem mit Programm (geschweifte Klammern setzen) Java Basics - Anfänger-Themen 11
E Klammern in einem String entfernen! Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben