1

I want to check if the string user entered has a balanced amount of ( and )'s

ex. ()( is not balanced (()) is balanced

def check(string):

        counter=0
        string=string.replace(" ","")

        if string[0] is "(":

           for x in string:
                if x is "(":
                        counter=counter+1
                elif x is ")":
                        counter=counter-1

           if counter1 is 0:
                print("Balanced")
           else:
                print("Unbalanced")
        else:
                print ("Unbalanced")

so this works, but how do I solve this problem with recursion? I am trying to think how I can make a variable decrease each time i call it recursively and once it's 0, stop.s

Óscar López
  • 232,561
  • 37
  • 312
  • 386
PhoonOne
  • 2,678
  • 12
  • 48
  • 76
  • 3
    Your algorithm gives false positives for strings like `)(`. – dan04 Aug 02 '13 at 00:26
  • A stack would be a good data structure to use here. – squiguy Aug 02 '13 at 00:57
  • 1
    @dan04 Same false positives for the two answers too. All should short circuit everything when a count is less than zero to return unbalanced. – Sylwester Aug 02 '13 at 01:27
  • 1
    I guess [Recursive method for parentheses balancing](http://stackoverflow.com/questions/18007995/recursive-method-for-parentheses-balancing-python) is related? – Sylwester Aug 02 '13 at 11:33

2 Answers2

4
>>> def check(mystr, barometer=0):
...     if not mystr:
...         return barometer
...     elif mystr[0] == "(":
...         return check(mystr[1:], barometer+1)
...     elif mystr[0] == ")":
...         return check(mystr[1:], barometer-1)
...     else:
...         return check(mystr[1:], barometer)
... 
>>> for s in ["()", "(()", "(())", "()()"]: print(s, check(s))
... 
() 0
(() 1
(()) 0
()() 0

0 means you're properly balanced. Anything else means you're not balanced

inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
3

A direct, equivalent conversion of the algorithm would look like this:

def check(string, counter=0):
  if not string:
    return "Balanced" if counter == 0 else "Unbalanced"
  elif counter < 0:
    return "Unbalanced"
  elif string[0] == "(":
    return check(string[1:], counter+1)
  elif string[0] == ")":
    return check(string[1:], counter-1)
  else:
    return check(string[1:], counter)

Use it like this:

check("(())")
=> "Balanced"

check(")(")
=> "Unbalanced"

Notice that the above algorithm takes into account cases where the closing parenthesis appears before the corresponding opening parenthesis, thanks to the elif counter < 0 condition - hence fixing a problem that was present in the original code.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • 1
    Could easily fix that with `elif counter < 0: return "Unbalanced"` – Sylwester Aug 02 '13 at 11:31
  • @Óscar López How do I make it so that if (has_letters_here) also return unbalanced? – PhoonOne Aug 02 '13 at 17:27
  • @Jenny And why is that unbalanced? balancing only refers to matching parenthesis. Anyway - it'd be a simple matter of adding one extra case: if the character at index `0` is not `(` or `)`, then it's unbalanced according to your definition – Óscar López Aug 02 '13 at 19:16
  • @Sylwester I wasn't sure if `)(` is "unbalanced" according to OP's definition, I believe she's only interested in the _number_ of parenthesis. But anyway, I updated my answer with your suggestion, thanks! – Óscar López Aug 02 '13 at 19:31