如何在python 3中检查不平衡的括号?

时间:2019-06-04 19:37:10

标签: python python-3.x

如何检查不平衡的括号? 我正在考虑使用括号-> {[()]}。 如何检查字符串是否不平衡?

示例:

  1. {[()]}->平衡
  2. {[(])}->不平衡
  3. {{[[(())]]}}->平衡

我正在尝试这种方式,但是没有用:

string = '{[(])}'

par = 0
col = 0
cha = 0
for i in string:
    if i == '{':
        cha+=1
    if i == '}':
        cha-=1
    if i == '[':
        col+=1
    if i == ']':
        col-=1
    if i == '(':
        par+=1
    if i == ')':
        par-=1
    if (cha < 0) or (col < 0) or (par < 0):
        print('Unbalanced')
        break
if (cha != 0) or (col != 0) or (par != 0):
    print('Unbalanced')
else:
    print('Balanced')

9 个答案:

答案 0 :(得分:3)

我认为您不能仅通过跟踪到目前为止已经看到的每个字符中的多少来验证字符串的平衡性。同样重要的是您以什么样的顺序看待它们,因此您必须以一种或另一种方式结合这种状态。这是一种方法-保留一堆“无与伦比”的括号。找到新的左括号时将其添加;找到与最近的左括号相匹配的右括号时,将其弹出;如果期望匹配但没有得到匹配,则返回False。如果您到达列表的末尾并且堆栈为空,则字符串是平衡的。

def balanced(s):
    pairs = {"{": "}", "(": ")", "[": "]"}
    stack = []
    for c in s:
        if c in "{[(":
            stack.append(c)
        elif stack and c == pairs[stack[-1]]:
            stack.pop()
        else:
            return False
    return len(stack) == 0


test_cases = ("{[()]}", "{[(])}", "{{[[(())]]}}")
for s in test_cases:
    print(s, balanced(s))

结果:

{[()]} True
{[(])} False
{{[[(())]]}} True

答案 1 :(得分:1)

您必须遍历字符串并存储传入的字符。每次最后两个字符分别为{}[]()时,只需删除这些字符并将新字符与最后存储的字符匹配(而不删除)即可。继续,直到到达字符串的末尾:如果删除了所有字符,则字符串是平衡的。

我发现折叠起来更容易:

>>> from functools import reduce
>>> def f(s): return reduce(lambda acc, x: acc[:-1] if acc and acc[-1]+x in ('{}', '[]', '()') else acc+x, s)

测试案例:

>>> f('{[()]}')
'' # balanced
>>> f('{[(])}')
'{[(])}' # unbalanced

有关命令式版本,请参见@Kevin的答案(if的两个分支等效于堆栈上的pop / push)。

编辑,如果您正在寻找伪palindrom({[]}是平衡的,但不是{}[]),则可以将每个字符与从相同位置开始的字符匹配结束。

首先,检查字符串是否具有偶数个字符:

>>> s = '{[()]}'
>>> len(s) % 2
0

如果是这种情况,请匹配字符:

>>> t, u = s[:len(s)//2], s[len(s)//2:]
>>> t, u
('{[(', ')]}')
>>> t, "".join(reversed(u))
('{[(', '}])')
>>> [o+c for o,c in zip(t, reversed(u))]
['{}', '[]', '()']

如果您只有匹配对,则字符串是平衡的:

>>> [o+c for o,c in zip(t, reversed(u)) if o+c not in ('{}', '[]', '()')]
[] # balanced

答案 2 :(得分:1)

创建一个堆栈。每次遇到:

  • 左括号
  • 左花括号
  • 左括号
  • 一无所有

...将左侧的“定界符”压入堆栈。当遇到右定界符时,将最顶部的元素弹出堆栈。弹出的元素将是最近看到的左定界符。确保左右定界符匹配。例如它们都是括号,或者都是括号。

如果堆栈上当前的左定界符是一个括号,而当前的右定界符是一个括号,则返回消息,表示事物不平衡。

如果您尝试从已经空的堆栈中弹出某些内容,请返回“ unbalanced”。

如果读入整个字符串,但是到结束时堆栈还不为空,则返回“ unbalanced”。

以上内容涵盖了字符串不平衡的所有情况。

如果您阅读了整个字符串并...

  • 完成后,堆栈为空
  • 您从未尝试过弹出一个空堆栈
  • 堆栈上的左定界符始终与遇到的右定界符匹配(例如,两者都是括号)

然后字符串是平衡的。返回“平衡”

答案 3 :(得分:1)

这是检查括号是否不平衡的替代代码:

def is_matched(expression):
    """
    Finds out how balanced an expression is.
    With a string containing only brackets.

    >>> is_matched('[]()()(((([])))')
    False
    >>> is_matched('[](){{{[]}}}')
    True
    """
    opening = tuple('({[')
    closing = tuple(')}]')
    mapping = dict(zip(opening, closing))
    queue = []

    for letter in expression:
        if letter in opening:
            queue.append(mapping[letter])
        elif letter in closing:
            if not queue or letter != queue.pop():
                return False
    return not queue

if __name__ == '__main__':
    import doctest
    doctest.testmod()

答案 4 :(得分:1)

def paranthesis(exprs):
    stack = []
    for char in exprs:
        if char in ["(","{","["]:
            stack.append(char)
        else:
            currchar = stack.pop()
            if currchar =="(":
                if char !=")":
                    return False
            if currchar == "{":
                if char != "}":
                    return False
            if currchar == "[":
                if char != "]":
                    return False
    if stack:
        print(stack)
        return False
    return True


if __name__ == "__main__":
    exprs = "({[]}]"

    if paranthesis:
        print("Balanced")
    else:
        print("Unbalanced")
}

答案 5 :(得分:0)

如果第一个和最后一个字符是匹配的对,则将它们剥离。重复。

如果您进入的第一个字符和最后一个字符都不匹配的状态,则说明字符串不平衡。

编辑:如@blhsing所指出的那样,这将无效。

新方法:寻找{}[](),然后将其删除。重复直到找不到更多。如果字符串为空,则说明该字符串是平衡的,否则不是。

答案 6 :(得分:0)

这是一种基于堆栈的方法,可将组字符转换为正/负数,以使其余逻辑独立于字符处理(并允许字符串中的其他字符):

def isBalanced(s):
    opened = [0] # {}=3/-3, []=2/-2, ()=1/-1, others:0/-4
    for n in [3-("{[( )]}"+c).index(c) for c in s]:
        if not n&3 : continue
        elif n>0   : opened.append(n)
        elif opened.pop() != -n: return False
    return opened == [0]

答案 7 :(得分:0)

我只会去除字符串的平衡块,直到我一无所有或无法进一步减少的不平衡字符串为止:

def is_matched(expr):
    expr = re.sub("[^][}{)(]+", "", expr)
    while expr:
        expr1 = re.sub(r"\(\)|\[\]|\{\}", "", expr)
        if expr1 == expr:
            return not expr1
        expr = expr1
    return True

>>> is_matched("{[()]}")
True
>>> is_matched("{[(])}")
False
>>> is_matched("{{[[(())]]}}")
True

第一个re.sub()删除了所有没有括号的内容。然后,循环将删除所有相邻的打开/关闭对,并重复进行直到我们用完字符串或用完相邻对。

答案 8 :(得分:-1)

来到@k​​evin的答案。以下内容通过了他的所有测试用例,但比较简单。

def balanced(s):
    if s.count('[') == s.count(']') and s.count('(') == s.count(')') and s.count('{') == s.count('}'):
        return True
    else:   
        return False

提出这样一个问题的目的不仅仅是看计数,而是整个括号是否有意义。如果在面试中被询问,您想让他们知道您了解其背后的动机。

Prob_test_cases = ('}{', '][', ')(')

大多数解决方案都可以通过平衡或括号匹配来满足上述要求,但理想情况下它们应该会失败。 您不会像在Prob_test_cases中那样编码代码或字符串。这就是我所拥有的。 时间长,但可以理解,无需任何堆栈,队列或数据结构实现。

def para_check(checkme):
    open = ['(', '[', '{']
    close = [')', ']', '}']
    # assume that the result is true
    result = True

    # if the input is not a list then convert it to list
    if type(checkme) is not list:
        checkme = list(checkme)

    # if it doesnt contain at least 2 elements then return false
    if len(checkme) < 2:
        result = False

    # if number of closing and opening paranthesis is not the same then it is not balanced
    count_check1 = checkme.count('[') == checkme.count(']')
    count_check2 = checkme.count('(') == checkme.count(')')
    count_check3 = checkme.count('{') == checkme.count('}')

    # if not all of the above are true then it is unbalanced and thus...
    if not all([count_check1, count_check2, count_check3]):
        result = False

    def recurser(checkme, first, last):
        '''
        here start can be '[,(,{' and end can be '],),}' respectively,
        Check for a given type of bracket (any 1 of 3) see if the 
        index of the first closing bracket is greater than the first 
        opening bracket and if yes then remove them since they are a pair.
        Repeat this forever for all 3 types of brackets.
        '''            
        if first in checkme and last in checkme:
            open_index = checkme.index(first)
            closed_index = checkme.index(last)
            
            if closed_index > open_index:
                checkme.pop(closed_index)
                checkme.pop(open_index)
                # recursion
                recurser(checkme, first, last)
            else:
                result = False

    recurser(checkme, '[', ']')
    recurser(checkme, '(', ')')
    recurser(checkme, '{', '}')

    if len(checkme) > 0:
        result = False

    return result