-->

Trying to stop an error with Stacks in python

2019-07-28 17:13发布

问题:

I'm trying to make a program that checks to make sure that the text is balanced in terms of brackets (so (),[],{} and not (),[,{}). I can get it to work when it is balanced, and when it is not balanced when it is missing a closing bracket (like the previous example). What I can't get it to do is come back as unbalanced if I'm missing a bracket on the left ((),],{}). I know it's trying to pop from an empty stack but can't figure out how to counter act that. My teacher has it in her Stack class that if it's trying to pop to an empty stack, then an exception is raised automatically, and I can't change her class, which is the problem, otherwise I just would have made that as false anyways and not be in this mess. So does anyone have any ideas of how to do it before that error is raised? Here's the code:

          from ListNode import *
          from Stack import Stack
          ch = 0
          s = 0
          check = True

        def parbalance():
              stack = Stack()
              user = input("Enter a file name: ")
              file = open(user)
              lines = file.readlines()
              for char in lines:
                 for ch in char:
                     #print(ch)
                 if ch in "([{":
                      stack.push(ch)
                 if ch in ")]}":
                    popStack = stack.pop()
                    if ch == "(" and popStack != ")":
                        check = False
                    elif ch == "[" and popStack != "]":
                        check = False
                    elif ch == "{" and popStack != "}":
                        check = False

                if stack.is_empty():
                      check = True
                       print("true")
                else:
                     check = False
                     print("false")




 parbalance()

In case it helps, here's her Stack class:

   from ListNode import *

   class Stack:
         def __init__(self):
           self.top = None

        def push(self, item):
           temp = ListNode(item)
           temp.set_link(self.top)
           self.top = temp
           #self.top = ListNode(item, self.top)

        def pop(self):
            if self.top == None:
                   raise Exception("Trying to pop from an empty stack")
             temp = self.top
             self.top = temp.get_link()
             return temp.get_item()

        def destroy(self):
            self.top = None

       def is_full(self):
            return False

       def is_empty(self):
            return self.top == None

回答1:

Use try to capture an error:

try:
    popStack = stack.pop()
except:
    # Stack is empty, set failure and bail from the function.
    check = False
    return

Also, note that your tests are backwards:

if ch == "(" and popStack != ")":

ch is the closing bracket and popStack is the opening bracket, so this should be:

if ch == ")" and popStack != "(":

Without this change, your code will recognize the string "(}" as balanced.

As a side note, consider returning True or False from the function instead of setting a global variable. Using global variables to return values from functions is not a good idea.



回答2:

You can put the code into a try except block. Once you catch an exception you know the stack underflows. Consequently there must be an unbalanced paranthesis.

By the way: I would not use the lengthy if else chain. Instead I would work it along the following lines:

pars = {'(':')', '[':']', '{':'}'}
....
try:
    ...
    if ch in pars.keys(): 
        stack.push(ch)

    if ch in pars.values():
        if ch != pars[stack.pop()]:
            return False;
except:
    return False;    

return stack.is_empty()

That way you could easily add other bracket symbols if required.