Troubleshooting Bracket Matching in Java StackADT Class

  • Thread starter STEMucator
  • Start date
In summary, the conversation was about creating a program to evaluate boolean expressions and the current focus was on a bracket matching algorithm. The code for the algorithm was shown, along with constructors and top, pop, and push methods for a StackADT class. The problem being encountered was with the code for matching brackets, as it was not throwing the proper exceptions. After some discussion and code revisions, the issue was narrowed down to a possible problem with strings like "{)}" and an error message was encountered.
  • #1
STEMucator
Homework Helper
2,076
140

Homework Statement



I'm trying to create a program which evaluates boolean expressions consisting of ()[]{}XYZ'!| 01TF. Right now I'm working on a bracket matching algorithm that will determine if the brackets match in a given expression.

The problem I'm getting is it's telling me I'm not throwing the proper exceptions for some reason even though I'm pretty sure I am inside my matching brackets code.

Here's my code which concerns this from my StackADT<T> class which I manually wrote. I used an ArrayList as my store. Just the bracket code, constructors, top, pop and push methods are below :

Constructors :

Code:
	//Used to create a BOUNDED capacity stack
	public StackADT(int capacity){
		isBoundedCapacity = true;
	    boundedCapacity = Math.abs(capacity);
	    Operators = new ArrayList<T>(boundedCapacity);
	}
	
	//Used to create an UNBOUNDED capacity stack
	public StackADT(){
		isBoundedCapacity = false;
		boundedCapacity = StackProtocol.INITIAL_CAPACITY;
		Operators = new ArrayList<T>(boundedCapacity);
	}

Top, pop and push :

Code:
	@Override
	public T top() throws StackUnderflowException{
		if(isEmpty())
			throw new StackUnderflowException();
		return Operators.get(topOfStack);
	}

    @Override
    public T pop() throws StackUnderflowException {
    	if(isEmpty())
    		throw new StackUnderflowException();
    	return Operators.remove(topOfStack--);
    }
   
    @Override
    public void push(T item) throws BoundedCapacityOverFlowException {
    	if(size() == boundedCapacity) {
    		if(isBoundedCapacity())
    			throw new BoundedCapacityOverFlowException();
    		else {
    			boundedCapacity *= 2;
    			Operators.ensureCapacity(boundedCapacity); //Automatically increases the stack bound
    		}
    	}
    	topOfStack++;
    	Operators.add(item);
    }

Matching brackets code ( Located in another class ):

Code:
	public void validateMatchingBrackets() throws MissmatchedBracketsException  {
		StackADT<Character> operationStack = new StackADT<Character>();  //Empty unbounded stack

		for(int i=0; i<booleanExpression.length(); i++) { //Loop over the expression
			Character c = booleanExpression.charAt(i);
			
		    if((c == '(' || c == '{' || c == '[')) //If c is an open bracket
		    	operationStack.push(c); //Push it onto the stack
		    
			else if(c == ')' || c == '}' || c == ']') { //Else if c is a close bracket
				if(operationStack.isEmpty()) //First check if the stack is empty which means we have no match
					throw new MissmatchedBracketsException(); //Throw the exception
								
				if( (c == ')' && operationStack.top() == '(') //If the stack wasn't empty, find the match and pop
				|| (c == ']' && operationStack.top() == '[')
				|| (c == '}' && operationStack.top() == '{') )
			    	operationStack.pop();
			} 
		}
		
		if(!operationStack.isEmpty())  //After the loop, if the stack is not empty, then throw an exception
			throw new MissmatchedBracketsException();
	}

If anyone could help me pinpoint what's wrong with my bracket code it would be very helpful :).
 
Physics news on Phys.org
  • #2
The problem I'm getting is it's telling me I'm not throwing the proper exceptions
Who/what is telling you that in which way?

I think your bracket matching algorithm gets problems with strings like "{)}" - it just ignores the ")".
 
  • #3
mfb said:
Who/what is telling you that in which way?

I think your bracket matching algorithm gets problems with strings like "{)}" - it just ignores the ")".

No my code will not have problems with "{)}" I just tested it in my GUI.

Also, I switched my code up a bit :

Code:
	public void validateMatchingBrackets() throws MissmatchedBracketsException, 
												BoundedCapacityOverFlowException, 
												StackUnderflowException {
		
		StackADT<Character> operationStack = new StackADT<Character>();  //Empty unbounded stack

		for(int i=0; i<booleanExpression.length(); i++) { //Loop over the expression
			Character c = booleanExpression.charAt(i);
			
		    if((c == '(' || c == '{' || c == '['))
		    	operationStack.push(c);

		    else if(c == ')' || c == '}' || c == ']') { //Else if c is a close bracket
				if(operationStack.isEmpty()) //First check if the stack is empty which means we have no match
					throw new MissmatchedBracketsException(); //Throw the exception

				if((c == ')' && operationStack.top() == '(') //If the stack wasn't empty, find the match and pop
				|| (c == ']' && operationStack.top() == '[')
				|| (c == '}' && operationStack.top() == '{'))
					operationStack.pop();
			}
		}
		
		if(!operationStack.isEmpty())  //After the loop, if the stack is not empty, then throw an exception
			throw new MissmatchedBracketsException();
	}

Now my method will throw any over and underflows back to the method caller. My method caller is a method called evaluateExpression() :

Code:
	public void evaluateExpression() {
		//Perform necessary validation
		try{
			validateVariablesAndOperators();
			validateMatchingBrackets();
		}
		catch (BoundedCapacityOverFlowException e) {
			e.getMessage();
		} 
		catch (StackUnderflowException e) {
			e.getMessage();
		}
		catch(InvalidVariableOrOperatorException e){
		    booleanExpression = e.toString();
			results = new boolean[] {
					false, false, false, false,
					false, false, false, false
			};
			if(gui != null) 
				gui.updateGUI();
			return;
		}
		catch(MissmatchedBracketsException e){
			booleanExpression = e.toString();
			results = new boolean[] {
					false, false, false, false,
					false, false, false, false
			};
			
			if(gui != null) 
				gui.updateGUI();
			return;
		}

Now for some reason, I get an error :

unreported exception assignment2_2402.BoundedCapacityOverFlowException; must be caught or declared to be thrown
t.validateMatchingBrackets();

Which makes no sense since I'm throwing these exceptions and dealing with them?
 
  • #4
Zondrina said:
No my code will not have problems with "{)}" I just tested it in my GUI.
I don't see how this gives an error (as it should).
The first "{" is recognized and put on the stack. For ")", the program enters the else if case, but does not do anything there, as the stack is not empty and stack.top gives "{" and c is ")".You should not get those error messages at all, unless you use a stack of fixed size and nest brackets too deep. Do you get them for all expressions? Did you check the state of the program just before it runs into errors? If you do not have a method to add breakpoints in your code to debug it, a lot of debug outputs should work as well.
 
  • #5
mfb said:
I don't see how this gives an error (as it should).
The first "{" is recognized and put on the stack. For ")", the program enters the else if case, but does not do anything there, as the stack is not empty and stack.top gives "{" and c is ")".

Here's a snip :

Code:
		for(int i=0; i<booleanExpression.length(); i++) { //Loop over the expression
			Character c = booleanExpression.charAt(i);
		    if((c == '(' || c == '{' || c == '[')) {
		    	try{operationStack.push(c);}
		    	catch(BoundedCapacityOverFlowException e) {
					booleanExpression = e.toString();
					results = new boolean[] {
							false, false, false, false,
							false, false, false, false
					};
					
					if(gui != null) 
						gui.updateGUI();
					return;
		    	}
		    }
		    else if(c == ')' || c == '}' || c == ']') { //Else if c is a close bracket
		    	try {
				if(operationStack.isEmpty()) //First check if the stack is empty which means we have no match
					throw new MissmatchedBracketsException(); //Throw the exception
				
				if( ((c == ')') && (operationStack.top() == '(' )) //If the stack wasn't empty, find the match and pop
				||  ((c == ']') && (operationStack.top() == '['))
				||  ((c == '}') && (operationStack.top() == '{')) )
					operationStack.pop();
		    	}

I thought that for "{)}" :

i = 0 implies '{' is put into stack entry 0 by the if statement.

i = 1 implies we skip the if and go to the else if.

So in the else if, first we check if the stack is empty because if we found a close bracket before we found an open bracket ( aka the stack is empty ) then we just want to throw the exception right away.

The stack isn't empty, so it skips over to the next if which result in :

if( ((c == ')') && (operationStack.top() == '(' )) getting executed, but top returns '{' in this case. So nothing happens. Nothing will continue to happen as all the other ifs don''t happen.

So now... i = 2 implies ... oooh so the stack is going to wind up being cleared as we did nothing with the ')'. So to fix this ... I need to change my logic around. I see why I was wrong now. Instead of '==' I should really be saying '!=' and throw the exception if that does happen to occur.

Here's the completed code that wound up working according to the test server :

Code:
	public void validateVariablesAndOperators() throws InvalidVariableOrOperatorException {
		String validTokens = "XYZ&|'()[]{} 01TF";
        for(int i=0; i<booleanExpression.length(); i++){
			char c = booleanExpression.charAt(i);
			
		    if(!validTokens.contains(""+c)) 
		    	throw new InvalidVariableOrOperatorException();
		}
	}
	public void validateMatchingBrackets() throws MissmatchedBracketsException {
		
		StackADT<Character> operationStack = new StackADT<Character>();  //Empty unbounded stack

		for(int i=0; i<booleanExpression.length(); i++) { //Loop over the expression
			Character c = booleanExpression.charAt(i);
		    if((c == '(' || c == '{' || c == '[')) {
		    	try{operationStack.push(c);}
		    	catch(BoundedCapacityOverFlowException e) {
					booleanExpression = e.toString();
					results = new boolean[] {
							false, false, false, false,
							false, false, false, false
					};
					
					if(gui != null) 
						gui.updateGUI();
					return;
		    	}
		    }
		    else if(c == ')' || c == '}' || c == ']') { //Else if c is a close bracket
		    	try {
				if(operationStack.isEmpty()) //First check if the stack is empty which means we have no match
					throw new MissmatchedBracketsException(); //Throw the exception
				Character tempPop = operationStack.pop();
				if( ((c == ')') && (tempPop != '(' )) //If the stack wasn't empty, find the match and pop
				||  ((c == ']') && (tempPop != '['))
				||  ((c == '}') && (tempPop != '{')) )
					throw new MissmatchedBracketsException();
		    	}
		    	catch(StackUnderflowException e){
					booleanExpression = e.toString();
					results = new boolean[] {
							false, false, false, false,
							false, false, false, false
					};
					
					if(gui != null) 
						gui.updateGUI();
					return;
		    	}
		   }
	}	
		if(!operationStack.isEmpty())  //After the loop, if the stack is not empty, then throw an exception
			throw new MissmatchedBracketsException();
	}

Thanks a lot for your help :)
 

Related to Troubleshooting Bracket Matching in Java StackADT Class

What is a stack?

A stack is a data structure that follows the "last in, first out" (LIFO) principle, meaning that the most recently added item is the first one to be removed. It can be visualized as a stack of plates, where the last plate added is the first one to be taken off.

What are the basic operations of a stack?

The basic operations of a stack include push (adding an item to the top of the stack), pop (removing an item from the top of the stack), peek (viewing the top item without removing it), and isEmpty (checking if the stack is empty).

What are some real-life examples of stacks?

Some real-life examples of stacks include a pile of books, a stack of dishes, and a stack of coins. In computer science, stacks are commonly used in programming languages, web browsers, and operating systems.

How are stacks different from queues?

While both stacks and queues are data structures, they differ in the order in which items are added and removed. As mentioned before, stacks follow the LIFO principle, while queues follow the "first in, first out" (FIFO) principle.

What are the advantages of using a stack?

Stacks have a simple and efficient structure, making them easy to implement and manipulate. They are also useful for managing function calls and keeping track of program states. Additionally, stacks can help prevent stack overflow errors by limiting the amount of memory used at one time.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
1
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
16
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
3K
  • Programming and Computer Science
Replies
2
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
3K
  • Programming and Computer Science
Replies
4
Views
2K
Back
Top