简体   繁体   English

试图平衡括号但不明白我的代码有什么问题

[英]Trying to balance parantheses but don't understand what's wrong with my code

I'm trying to balance parenthesis on python using Stacks.我正在尝试使用 Stacks 来平衡 python 上的括号。 I've been trying to figure out what's wrong but I don't get it.我一直试图弄清楚出了什么问题,但我不明白。 Here's the code I wrote:这是我写的代码:

class Stack:

def __init__(self):
    self.opens = []
    self.closes = []

def empty_opens(self):
    return self.opens == []

def empty_closes(self):
    return self.closes == []

def add_opens(self, item):
    return self.opens.append(item)

def add_closes(self, item):
    return self.closes.append(item)

def is_empty_opens(self):
    return len(self.opens) == 0

def remove_opens(self):
    if not self.is_empty_opens():
        return self.opens.pop(0)

def is_empty_closes(self):
    return len(self.closes) == 0

def remove_closes(self):
    if not self.is_empty_closes():
        return self.closes.pop()


def checker(string):
open = "([{"
close = ")]}"
p = Stack()
for i in string:
    if i == "(" or i == "[" or i == "{":
        p.add_opens(i)
    elif i == ")" or i == "]" or i == "}":
        p.add_closes(i)
if len(p.opens) != len(p.closes):
    return False
else:
    for a in p.opens:
        for b in reversed(p.closes):
            if open.index(a) == close.index(b):
                p.remove_opens()
                p.remove_closes()
if len(p.opens) == 0 and len(p.closes) == 0:
    return True
else:
    return False

The code works overall but it seems that it doesn't remove the last values of the "for" loop.该代码总体上有效,但它似乎没有删除“for”循环的最后一个值。 I added a print after the "for" loops to try and figure it out and this is what i got:我在“for”循环之后添加了一个打印来尝试弄清楚,这就是我得到的:

    ...
    else:
    for a in p.opens:
        for b in reversed(p.closes):
            if open.index(a) == close.index(b):
                p.remove_opens()
                p.remove_closes()
    print(p.opens)
    print(p.closes)
if len(p.opens) == 1 and len(p.closes) == 1:
   ...

Python Console:

checker("{[()]}")
['(']
[')']
False

checker("{[(]]}")
['[', '(']
[']', ']']
False

I also tried to change the code, instead of using .index() I tried to use range(len()), but it didn't work again:我还尝试更改代码,而不是使用 .index() 我尝试使用 range(len()),但它再次不起作用:

    ...
    else:
    for a in range(len(p.opens)):
        for b in reversed(range(len(p.closes))):
            if a == b:
                p.remove_opens()
                p.remove_closes()
    print(p.opens)
    print(p.closes)
if len(p.opens) == 0 and len(p.closes) == 0:
   ...

  Python Console:

  checker("{[()]}")
  ['(']
  [')']
  False

  checker("{[(]]}")
  ['(']
  [']']
  False

This is probably a basic mistake but I'm slowly losing my mind over this so I ask if anyone could help.这可能是一个基本错误,但我正在慢慢失去理智,所以我问是否有人可以提供帮助。

Note on the code:代码注意事项:

What I'm trying to do in my code is through a class create 2 lists, one for the open parenthesis: "(, [, {" and another one for the close parenthesis: "), ], }" .我试图在我的代码中做的是通过一个类创建 2 个列表,一个用于左括号: "(, [, {"另一个用于右括号: "), ], }"

The class has the simple Stack methods of adding or removing from the list.该类具有在列表中添加或删除的简单 Stack 方法。

Regarding the code itself, what I'm trying to do first is separate the characters that are parenthesis from the characters that aren't.关于代码本身,我首先要做的是将括号中的字符与非括号中的字符分开。 If the code finds a parenthesis that is open, it adds to the "opens" list and if it's close, it adds to the "closes" list.如果代码找到一个打开的括号,它会添加到“打开”列表中,如果它是关闭的,它会添加到“关闭”列表中。

After that it checks how many items there are in each list and if they are not the same then it means right away that they are unbalanced.之后,它会检查每个列表中有多少项,如果它们不相同,则立即意味着它们是不平衡的。

Now the tricky part.现在是棘手的部分。 If there are the same amount of parenthesis open and closed I want the code to check each one.如果打开和关闭的括号数量相同,我希望代码检查每个括号。 From what I understand, for parenthesis to be balanced, the first open parenthesis in the list "opens" needs to be equal to the last closed parenthesis in the "closes" list.据我了解,为了平衡括号, “opens”列表中的第一个左括号需要等于“closes”列表中的最后一个括号。

Ex:前任:

Input: { [ ( ) ] }输入: { [ ( ) ] }

opens_list = [ '{', '[', '(' ] opens_list = [ '{', '[', '(' ]

'{' = 1 , '[' = 2 , '(' = 3 '{' = 1 , '[' = 2 , '(' = 3

closes_list = [ ')', ']', '}' ] closes_list = [ ')', ']', '}' ]

')' = 1 , '[' = 2 , '{' = 3 ')' = 1 , '[' = 2 , '{' = 3

So they have to match, Opens(1) = Closes(3), Opens(2) = Closes(2) and Opens(3) = Closes(3)所以他们必须匹配, Opens(1) = Closes(3), Opens(2) = Closes(2) and Opens(3) = Closes(3)

Based on this what i did was reverse the closes list so that each index has to correspond.基于此,我所做的是反转关闭列表,以便每个索引都必须对应。 In the beggining of the code I wrote:在我写的代码的开头:

def checker(string):
 open = "([{"
 close = ")]}"
 ...

So what I'm trying to do is take the first character in the opens_list, "{" , check what index it has in the "open variable" , it has the 3rd index and do the same for the closes list.所以我想要做的是获取 opens_list 中的第一个字符"{" ,检查它在"open variable"中的索引,它具有第三个索引,并对closes列表执行相同操作。

If they have the same index it removes them.如果它们具有相同的索引,则会删除它们。 In the end, if both list don't have any elements then it's balanced.最后,如果两个列表都没有任何元素,那么它就是平衡的。

This is a bit messy, english is not my first language and I don't know all the right concepts of things in python but I hope it's understandable.这有点乱,英语不是我的第一语言,我不知道 python 中所有正确的概念,但我希望它是可以理解的。 I honestly just want to know what's wrong so I don't repeat the same mistake in the future.老实说,我只是想知道出了什么问题,这样我以后就不会再犯同样的错误了。 If anyone can understand this and help, I would appreciate a lot.如果有人能理解这一点并提供帮助,我将不胜感激。

Checking for matching delimiters using a stack only requires 3 basic operations:使用堆栈检查匹配的分隔符只需要 3 个基本操作:

  1. If a character is an opening delimiter, add it to the stack如果字符是开始分隔符,则将其添加到堆栈中
  2. If a character is a closing delimiter, pop the stack and see if it matches the closing character.如果字符是结束分隔符,则弹出堆栈并查看它是否与结束字符匹配。
  3. Checking if the stack is empty when the input is exhausted.当输入耗尽时检查堆栈是否为空。

There's no real need for a dedicated Stack class;没有真正需要专用的Stack类; all three operations are easily implemented using a bare list.所有三个操作都可以使用裸列表轻松实现。

def checker(string):
    match = dict(["()", "{}", "[]"])  # Mapping of opening delimiter to its closing partner
    st = []  # Initially empty stack
    for c in string:
        if c in match:  # Push an opening delimiter
            st.append(c)
        elif c in match.values():
            # Try to pop the most recent opening delimiter;
            # return False if that fails or it doesn't match the closing delimiter
            if not st or match[st.pop()] != c:
                return False

    # Check if there were any unclosed delimiters
    return (not st)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM