0

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

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

或者

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

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

'I am in the middle of writing this ('

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

总结一下要求:

  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
4

3 回答 3

2

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

于 2012-07-19T08:45:21.240 回答
1

这是一个基于堆栈的解决方案。仅当输入是某个控制字符时才从整个字符串中计算大括号会更快,但这很棘手,因为在键入之前进行了文本选择和其他原因。这也不是很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()
于 2012-07-19T09:41:14.293 回答
1

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

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('())(')
于 2019-08-22T16:44:36.540 回答