algorithmrecursiondata-structures

Recursive algorithm to check whether String has Balanced Parenthesis


Possible Duplicate:
Basic Recursion, Check Balanced Parenthesis

I came across this problem in Algorithm Design Manual recently, even though the stack based algorithm is very trivial I want to write a recursive algorithm for this problem, However with being a noob in recursion I am not able to come up with much, so can anyone help me with this problem?

PS I saw other posts about this question only but they are not very efficient and those who are, aint very explanotry.


Solution

  • Background: The problem of finding if parenthesis are balanced is actually a decision problem, and the language1 describing it is a context-free language.
    Context free grammers can be parsed using an automaton with a stack2

    So, the following iterative solution can be achieved to this problem:

    iterative(str):
      stack <- empty stack
      for each char in str:
         if char is open paranthesis: //push the paranhtesis to stack
             stack.push(char)
         else if char is close parantesis: //if close paranthesis - check if it is closing an open parenthesis
             if stack.head() == matchingParanthesis(char):
                stack.pop()
             else: //if the closing parenthesis do not close anything previously opened, return false
                 return false 
       //end of loop - check if all opened parenthesis were closed:
       return stack.isEmpty()
    

    The idea is that the parenthesis representing the opened scope is in the head of the stack, and each closing parenthesis - you can validate if it is closing the appropriate open parenthesis by looking the head of the stack.

    Note: It is easy to see that for a single type parenthesis we could use an integer to mimic the stack (since we only actually needed to count the number, and don't care for the type of the parenthesis).

    Also, since a loop+stack algorithms are really similar to recursion actually, we can derive the following recursive algorithm:

    checkValidty(str,currentParenthesis,currentIndex): 
    //currentIndex is a common variable, changed by reference to affect all levels of recursion!
       while (currentIndex < str.size()):
          char <- str[currentIndex]
          currentIndex <- currentIndex + 1
          if char is open paranthesis: 
            //if the recursive call is unseccesfull - end the check, the answer is no
             if !checkValidity(str,char,currentIndex): 
                return false
          else if char is close parantesis: 
             if currentParenthesis == matchingParanthesis(char):
                return true
             else: //if the closing parenthesis do not close anything previously opened, return false
                 return false 
       //end of loop - check if all opened parenthesis were closed:
       return currentParenthesis == nil
    

    Invoke with checkValidty(str,nil,0) - where str is the validated string.

    It is easy to see that the iterative and recursive algorithms are actually the same, in the second we use the call stack and the variable lastParenthesis as the head of the stack.


    (1) The language is all the words accepted by the problem. for example (w) is in the language while )w( is not.
    (2) to be exact: some grammers need a non-deterministic automata and a stack, but this is a bit more theoretical thing, and is not the issue here.