我有一项任务是创建一个函数,从最里面的对开始,反转常规括号序列中的任何字符串字符。字符串序列可以有空格,标点符号,字母和大括号。所以结果应该是刺痛。
实施例
对于字符串
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
我应该如何纠正或调整我的代码,以便在最后两个示例中获得正确的结果?
代码调整
我试图考虑答案和提示,但我不能使用递归。当只有两个位于:"..(...) (...).., .."
所以我做了以下代码:
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"
为了得到正确的答案应该改变什么?
答案 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"
。由于这只适用于最里面的组,因此应该在进行更改时重复该过程,因此循环。