如何更改获得正确答案的周期?

时间:2017-05-16 17:55:27

标签: python string python-3.x cycle

我有一项任务是创建一个函数,从最里面的对开始,反转常规括号序列中的任何字符串字符。字符串序列可以有空格,标点符号,字母和大括号。所以结果应该是刺痛。

实施例

对于字符串

s = "a(bc)de"

输出应为

reverseParentheses(s) = "acbde".

我已经编写了以下代码来解决这个问题:

s_i = s   
for i in range(s.count('(')):
    # reverse letters inside parenthesis
    s_i = s_i.replace(s_i[s_i.rindex('(')+1:s_i.index(')')], s_i[s_i.rindex('(')+1:s_i.index(')')][::-1])
    # delete outward parenthesis
    s_i =s_i[:s_i.rindex('(')] + s_i[s_i.rindex('(')+1:]
    # delete inward parenthesis
    s_i =s_i[:s_i.index(')')] + s_i[s_i.index(')')+1:]
    i += 1
print(s_i)

然而,我对跟随字符串的结果是错误的:

s = "abc(cba)ab(bac)c"

应该是

abcabcabcabc

我得到了

abccabbaabcc

并且

s = "The ((quick (brown) (fox) jumps over the lazy) dog)"

应该是这样的:

The god quick nworb xof jumps over the lazy

但我只得到:

The god quick xof nworb jumps over the lazy

我应该如何纠正或调整我的代码,以便在最后两个示例中获得正确的结果?

代码调整

我试图考虑答案和提示,但我不能使用递归。当只有两个位于:"..(...) (...).., .."

时,我对parantacies的问题进行了解决

所以我做了以下代码:

def reverse(s):
#ensure parens are in pairs
if '(' not in s and ')' not in s:
    while '(' in s:
            s = s.replace(s[s.rindex('(')+1:s.index(')')], s[s.rindex('(')+1:s.index(')')][::-1])
            s = s[:s.rindex('(')] + s[s.rindex('(')+1:]
            s = s[:s.index(')')] + s[s.index(')')+1:]
    return s
else:
    if (s[s.index(')'):s.rindex('(')+1] == ''):
        while '(' in s:
                s = s.replace(s[s.rindex('(')+1:s.index(')')], s[s.rindex('(')+1:s.index(')')][::-1])
                s = s[:s.rindex('(')] + s[s.rindex('(')+1:]
                s = s[:s.index(')')] + s[s.index(')')+1:]
        return s
    elif (s[s.index(')'):s.rindex('(')+1] != ''):
        betw = s[s.index(')')+1:s.rindex('(')]
        part1 = s[:s.index(')')+1]
        part2 = s[s.rindex('('):]
        part1 = part1.replace(part1[part1.rindex('(')+1:part1.index(')')], part1[part1.rindex('(')+1:part1.index(')')][::-1])
        part1 = part1[:part1.rindex(')')]
        part2 = part2.replace(part2[part2.rindex('(')+1:part2.index(')')], part2[part2.rindex('(')+1:part2.index(')')][::-1])
        part2 = part2[part2.rindex('(')+1:]
        s = part1+betw+part2
        s = s[:s.rindex('(')] + s[s.rindex('(')+1:]
        s = s[:s.index(')')] + s[s.index(')')+1:]
        while '(' in s:
            s = s.replace(s[s.rindex('(')+1:s.index(')')], s[s.rindex('(')+1:s.index(')')][::-1])
            s = s[:s.rindex('(')] + s[s.rindex('(')+1:]
            s = s[:s.index(')')] + s[s.index(')')+1:]
        return s
    else:
        while '(' in s:
            s = s.replace(s[s.rindex('(')+1:s.index(')')], s[s.rindex('(')+1:s.index(')')][::-1])
            s = s[:s.rindex('(')] + s[s.rindex('(')+1:]
            s = s[:s.index(')')] + s[s.index(')')+1:]
        return s

但是,我认为它在以下示例中表现不佳:

s = "abc(147)ab(123)c(12)asd"

答案应该是:"abc741ab321c21asd",但我得到"abc12c321ba147asd"

为了得到正确的答案应该改变什么?

3 个答案:

答案 0 :(得分:1)

您的解决方案无效的原因是因为括号不匹配:

"abc(cba)ab(bac)c"
"   (cba)ab(bac) "
"       )ab(     "

你的方法最终不起作用:相反,我建议你找出一种更好的方法来确定哪些parens匹配:

def find_paren_set(str):
    # magic
    return left, right

一旦掌握了这项功能,您就可以while has_parens(str):直到完成为止。

附加说明:每次反转某个部分时,内部的parens都会被交换,((ob))将变为)bo(

答案 1 :(得分:1)

由于看起来可能出现任意数量的()对,我建议实现一个递归函数,只要成对的parens仍存在于第一个以外的级别,就可以调用它:

def reverseParentheses(s):
    # ensure parens are in pairs
    assert '(' in s and ')' in s

    while '(' in s:
        # Go through and swap strings/letters in the innermost parens only.
        # Then reassign `s` to that newly formatted string 
        #  (after taking out those parens)
        # Call the function again until it purges the string of all parens
        reverseParentheses(s)
    return s

答案 2 :(得分:1)

而不是手动执行此操作,请使用专门处理字符串操作的regular expression模块re

import re

def reverseParentheses(s):
    def reverse_interior(m):
        s = m.group()
        return s[-2:0:-1]
    old = ""
    while old != s:
        old = s
        s = re.sub(r'(\([^\(\)]*\))',reverse_interior,s)
    return s

assert reverseParentheses("a(bc)de") == "acbde"
assert reverseParentheses("abc(cba)ab(bac)c") == "abcabcabcabc"
assert reverseParentheses("The ((quick (brown) (fox) jumps over the lazy) dog)") == "The god quick nworb xof jumps over the lazy"
assert reverseParentheses("((ob))") == "ob"

此处表达式'(\([^\(\)]*\))'会搜索()之间的任何内容,这是[^\(\)]*中定义的字符之一,而后者代表任何数字字符不是(),这样它会搜索匹配的最里面的组,然后我使用函数re.sub用该辅助函数替换字符串中的那些,取一个字符串形式"(xyz)"并返回"zyx"。由于这只适用于最里面的组,因此应该在进行更改时重复该过程,因此循环。