【问题标题】:Reversing substrings in a string in python在python中反转字符串中的子字符串
【发布时间】:2019-05-02 07:31:36
【问题描述】:

我正在编写一个程序来反转python中括号中的子字符串。结果字符串不应包含任何括号。我正在打印 b1 和 b2 以及 ch 用于测试目的。似乎在while循环内for循环的第二次迭代中,b1变量没有用正确的索引更新。 我尝试编写如下解决方案:

def reverseParentheses(s):
    r = s
    sstring = ''
    astring = ''
    b1 = b2 = 0
    count = 0
    for ch in s:
        if ch == '(':
            count+=1
        elif ch ==')':
            count+=1
        else:
            pass

    while True:
        b1 = b2 = 0
        for ch in r:
            if ch == '(':
                b1 = r.index(ch)
                print("b1= ",b1, ch)
            if ch == ')':
                b2 = r.index(ch)
                print("b2= ",b2, ch)
                sstring = r[b2-1:b1:-1]
                print(r)
                print(sstring)
                astring = r[0:b1]+sstring+r[b2+1:]
                print(astring)
                r = astring
                break
        if len(astring)+count == len(s):
            break
    return r



s = "a(bcdefghijkl(mno)p)q"
print(reverseParentheses(s))

这是我得到的输出: aonmpbcdefghijklq 这是我期望的输出: apmnolkjihgfedcbq

【问题讨论】:

  • 你的预期输出是什么?
  • 它输出: b1= 1 ( b1= 1 ( b2= 17 ) a(bcdefghijkl(mno)p)q onm(lkjihgfedcb aonm(lkjihgfedcbp)q b1= 4 ( b2= 17 ) aonm (lkjihgfedcbp)q pbcdefghijkl aonmpbcdefghijklq aonmpbcdefghijklq.最后一行是程序的最终结果
  • 在最深的嵌套括号级别上查找括号索引,在中间反转字符,重复直到没有括号为止
  • 不要在 cmets 中回答,edit 你的问题要包括预期输出和实际输出
  • 是的,这是对问题的正确评估。

标签: python python-3.x substring


【解决方案1】:

处理嵌套分隔符的一个好方法是使用堆栈。当您遇到一个打开的分隔符时,将一个新集合推送到堆栈中。 pop() 当您找到关闭时。这将保持嵌套顺序正确。

这是一种方法(它不检查平衡括号,但不难添加):

s = "a(bcdefghijkl(mno)p)q"
stack = [[]] # accumulate letters in stack[0]
for l in s:
    if l == '(':
        stack.append([])        # start a new level
    elif l == ')':
        sub = stack.pop()[::-1] # pop the last level and reverse
        stack[-1].extend(sub)   # add to current 
    else:
        stack[-1].append(l)     # add to current

''.join(stack[0]) #'apmnolkjihgfedcbq'

【讨论】:

    【解决方案2】:

    一种方法是找到括号的位置,然后由内而外反转(所以偶数个括号之间的保持不变),最后去掉括号:

    s = "a(bcdefghijkl(mno)p)q"
    
    leftp = reversed([pos for pos, char in enumerate(s) if char == "("])
    rightp = [pos for pos, char in enumerate(s) if char == ")"]
    
    for i in zip(leftp,rightp):
        subs = s[i[0]+1:i[1]][::-1]
        s = s[:i[0]+1]+subs+s[i[1]:]
    for c in ["(", ")"]:
        s = s.replace(c, "")
    print(s) # Outputs "apmnolkjihgfedcbq"
    

    编辑

    对于未嵌套的括号,正如 .@Mark Meyer 所指出的,您可以按照here 的描述找到它们,并且适用相同的规则

    def find_parens(s):
        toret = {}
        pstack = []
        for i, c in enumerate(s):
            if c == '(':
                pstack.append(i)
            elif c == ')':
                if len(pstack) == 0:
                    raise IndexError("No matching closing parens at: " + str(i))
                toret[pstack.pop()] = i
        if len(pstack) > 0:
            raise IndexError("No matching opening parens at: " + str(pstack.pop()))
        return toret
    
    s = "a(bcd)efghijkl(mno)pq"
    parens = find_parens(s)
    
    for leftp, rightp in parens.items():
        subs = s[leftp+1:rightp][::-1]
        s = s[:leftp+1]+subs+s[rightp:]
    for c in ["(", ")"]:
        s = s.replace(c, "")
    print(s) # Outputs "adcbefghijklonmpq" 
    

    【讨论】:

    • 似乎对字符串有问题:s = "(ab)cdefghijklmno(pq)" --> "conmlkjihgfedcbadefghijklmnopq"
    • 现在比你的更健壮,呵呵:P
    • 现在看起来很防弹。
    猜你喜欢
    • 1970-01-01
    • 2010-10-30
    • 2012-01-11
    • 1970-01-01
    • 2013-06-22
    相关资源
    最近更新 更多