【问题标题】:Count matching brackets in python string计算python字符串中匹配的括号
【发布时间】:2012-07-19 08:27:18
【问题描述】:

用户键入一个包含正则表达式的字符串,如下所示:

'I have the string "(.*)"'

'when user enters (\d+) times text "(.*)" truncate spaces'

我需要将每个匹配括号的出现计数为用户类型,因此上面的文本将为第一个文本返回计数 1,为第二个文本返回 2。另一方面,不应该计算没有匹配的括号:

'I am in the middle of writing this ('

我还想避免计算嵌套括号。 由于此代码将在 vim 中的 每个 击键的某些情况下执行(它是 UltiSnips 的 sn-p 的一部分,因此当我创建 sn-p 并输入给定的占位符时,此计数函数应评估我在每个新字符上输入的内容)它需要快速;)

总结要求:

  1. 计算括号对
  2. 不要计算没有匹配的括号
  3. 不计算嵌套括号
  4. 计数快;)

根据要求 - 这是我完成这项工作的初步努力: https://gist.github.com/3142334

它有效,但不幸的是它也计算内括号,所以我需要对其进行更多调整。

这是另一种只计算外括号的解决方案:

def fb(string, c=0):
    left_bracket = string.find("(")
    if left_bracket > -1:
        string = string[left_bracket + 1:]
        right_bracket = string.find(")")
        if right_bracket > -1:
            if string[:right_bracket].find("(") == -1:
                c += 1
            string = string[right_bracket + 1:]
        return fb(string, c)
    else:
        return c

【问题讨论】:

  • 你能发布你目前的工作吗?
  • 请在您的需求摘要中添加以下内容:0: Show what I've thought of or done so far
  • 现在我只是在 ipython 控制台中进行实验。我认为这个必须递归才能以可维护的方式发现问题。
  • 通常你会使用堆栈之类的东西来进行这种括号配对。在您的 vim 环境中,击键之间的状态是否保持不变,或者您是否需要(重新)处理每次击键时的整个字符串?
  • 不幸的是,我每次都需要重新处理字符串:)

标签: python


【解决方案1】:

对于这类任务,使用 Stack ADT 很有用。每当你看到一个左括号将它放入堆栈,当你看到右括号从堆栈中弹出它并增加计数器。

【讨论】:

  • 实际上也可以使用一个简单的计数器来完成这项任务,但总体思路非常有帮助 :) 谢谢 :)
【解决方案2】:

这是一个基于堆栈的解决方案。当输入是某个控制字符时,仅从整个字符串中计算大括号会更快,但这很棘手,因为在键入之前进行了文本选择和其他原因。这也不是很pythonic,但它似乎工作并且相对较快:

#!/usr/bin/env python

import re

def bracecounter(s):
    count = 0; open = 0; braces = []
    for c in s:
        if c in '()':
            braces.append(c)
            if c == '(':
                open += 1
            else:
                if ''.join(braces[-2:]) == '()':
                    braces = braces[:-2]
                    if open == 1:
                        count += 1
                    open -= 1
                else:
                    pass # closing brace without matching opening brace
    return count

fix = [
    (1, 'I have the string "(.*)"'),
    (2, 'when user enters (\d+) times text "(.*)" truncate spaces'),
    (0, 'I am in the middle of writing this ('),
    (1, ') Nested ((braces) will (not) count))))))).'),
    ]

def test():
    for exp, s in fix:
        res = bracecounter(s)
        assert exp == res, "Brace count %s != %s for '%s'" % (res, exp, s)

if __name__ == '__main__':
    test()

【讨论】:

  • pielgrzym 发布的递归解决方案比这快了大约 4 倍。
【解决方案3】:

我正在解决一个括号计数作业问题,并使用列表作为堆栈是我想出来的方式,代码如下:

def bracket_match(text):

    stack = []
    pairs = 0

    #iterate through the string
    for letter in text:

        if letter == '(':
            stack.append(letter)

        elif letter == ')':

            if len(stack) == 0:
                pass
            else:
                stack.pop()
                pairs += 1

    return pairs

bracket_match('())(')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 2022-07-06
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 2011-07-22
    • 2016-02-28
    相关资源
    最近更新 更多