简体   繁体   English

在 Python 中递归检查平衡字符串

[英]Recursively checking for balanced string in Python

I've been stuck on this for quite a while, I can't come up with recursive cases, in particular I don't understand how to split a list to check if its balanced.我已经坚持了很长一段时间,我无法提出递归案例,特别是我不明白如何拆分列表以检查其是否平衡。 If someone could help me I would really appreciate it.如果有人可以帮助我,我将不胜感激。

def balanced_str(s):
    """
    Return whether string s is balanced or not. A balanced string is one where
    the string contains no parentheses
    >>> balanced_str('a')
    True
    >>> balanced_str('abbcsi')
    True
    >>> balanced_str('ak)')
    False
    >>> balanced_str('hah(dh')
    False
    >>> balanced_str('()')
    True
    >>> balanced_str('(hghghgh)')
    True
    >>> balanced_str('((a))')
    True
    >>> balanced_str('((hahsh))')
    True
    >>> balanced_str('(gfjf)h)')
    False
    >>> balanced_str('(hhg)(hfhg)')
    True
    """
    if '(' not in s and ')' not in s:
        return True
    elif '(' in s and ')' not in s or ')' in s and '(' not in s:
        return False
    else:
        if s[0] == '(' and s[len(s) - 1] == ')':
            return balanced_str(s[1:len(s) - 2])

A simple, iterative approach could be to create a tiny lexer.一种简单的迭代方法可能是创建一个小型词法分析器。 It will increase a counter o when an opening parentheses ( appears, and decreases the counter if a closing parentheses ) appears.当出现左括号(出现,如果出现右括号,则减少计数器)时,它将增加计数器o If meanwhile searching the string the counter o gets negative, or by the end of the loop the counter o is not zero, the test fails:如果同时搜索字符串计数器o负,或者在循环结束时计数器o不为零,则测试失败:

def balanced_str(s):
   o = 0
   for c in s:
       if c == ')':
          if o <= 0:
             # this only happens if there are more closing
             # parentheses then opening parentheses.
             return False

          o -= 1
       elif c == '(':
           o += 1

   # all parentheses should be closed
   return o == 0

For your test cases this approach works:对于您的测试用例,这种方法有效:

>>> balanced_str('a')
True
>>> balanced_str('abbcsi')
True
>>> balanced_str('ak)')
False
>>> balanced_str('hah(dh')
False
>>> balanced_str('()')
True
>>> balanced_str('(hghghgh)')
True
>>> balanced_str('((a))')
True
>>> balanced_str('((hahsh))')
True
>>> balanced_str('(gfjf)h)')
False
>>> balanced_str('(hug)(hfhg)')
True

For a recursive approach, you can create a small helper function that takes more parameters (ie. the number of parens we've seen so far).对于递归方法,您可以创建一个带有更多参数的小型辅助函数(即我们目前看到的括号数量)。 Below this approach, you can see how you can do it without a helper function through the use of global在这种方法下面,您可以看到如何在没有辅助函数的情况下通过使用global

def balanced_str(s):
    """
    Return whether string s is balanced or not. A balanced string is one where
    the string contains no parentheses
    >>> balanced_str('a')
    True
    >>> balanced_str('abbcsi')
    True
    >>> balanced_str('ak)')
    False
    >>> balanced_str('hah(dh')
    False
    >>> balanced_str('()')
    True
    >>> balanced_str('(hghghgh)')
    True
    >>> balanced_str('((a))')
    True
    >>> balanced_str('((hahsh))')
    True
    >>> balanced_str('(gfjf)h)')
    False
    >>> balanced_str('(hhg)(hfhg)')
    True
    """
    return helper(s,0)

def helper(s, numP):
    if len(s)==0: return numP==0
    if numP < 0: return False
    if s[0] == "(": return  helper(s[1:], numP+1)
    elif s[0] == ")": return  helper(s[1:], numP-1)
    return helper(s[1:], numP)

Without helper:没有帮手:

def balanced_str(s):
    """
    Return whether string s is balanced or not. A balanced string is one where
    the string contains no parentheses
    >>> balanced_str('a')
    True
    >>> balanced_str('abbcsi')
    True
    >>> balanced_str('ak)')
    False
    >>> balanced_str('hah(dh')
    False
    >>> balanced_str('()')
    True
    >>> balanced_str('(hghghgh)')
    True
    >>> balanced_str('((a))')
    True
    >>> balanced_str('((hahsh))')
    True
    >>> balanced_str('(gfjf)h)')
    False
    >>> balanced_str('(hhg)(hfhg)')
    True
    """
    try:
        numP
    except NameError:
        numP = 0
        global numP
    if len(s)==0: return numP==0
    if numP < 0: return False
    if s[0] == "(":
        numP += 1
        return balanced_str(s[1:])
    elif s[0] == ")":
        numP -= 1
        return balanced_str(s[1:])
    return balanced_str(s[1:])

Here's my candidate solution:这是我的候选解决方案:

def balanced(iterable, semaphore=0):

    if semaphore < 0 or len(iterable) == 0:
        return semaphore == 0

    first, *rest = iterable

    return balanced(rest, semaphore + { "(": 1, ")": -1 }.get(first, 0))

I've renamed balanced_str() to balanced() since if it's written properly, it should handle strings or lists of characters (ie iterables ):我已将balanced_str()重命名为balanced()因为如果它写得正确,它应该处理字符串或字符列表(即iterables ):

>>> balanced('a')
True
>>> balanced(['a', 'b', 'b', 'c', 's', 'i'])
True
>>> balanced('ak)')
False
>>> balanced(['h', 'a', 'h', '(', 'd', 'h'])
False
>>> balanced('()')
True
>>> balanced(['(', 'h', 'g', 'h', 'g', 'h', 'g', 'h', ')'])
True
>>> balanced('((a))')
True
>>> balanced(['(', '(', 'h', 'a', 'h', 's', 'h', ')', ')'])
True
>>> balanced('(gfjf)h)')
False
>>> balanced(['(', 'h', 'h', 'g', ')', '(', 'h', 'f', 'h', 'g', ')'])
True

I believe this is true of other proposed solutions as well, not just mine.我相信其他提议的解决方案也是如此,而不仅仅是我的。

Here's a recursive approach.这是一种递归方法。 I think this is pretty concise and intuitive我认为这非常简洁直观

def is_balanced(s, c=0):
    if len(s) == 0:
        if c == 0:
            return True
        else:
            return False
    elif s[0] == "(":
        c = c + 1
        return is_balanced(s[1 : len(s)], c)
    elif s[0] == ")":
        c = c - 1
        return is_balanced(s[1 : len(s)], c)
    else:
        return is_balanced(s[1 : len(s)], c)

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

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