问题描述如下:
编写一个递归函数,给定一个字符串,检查该字符串是否 由彼此相等的两个半部分组成(即s = s1 + s2,其中s1 = s2),施加了约束,即等于运算符==只能应用于长度≤1的字符串。如果字符串的长度是 奇怪,返回错误。
我用Python 2.7编写了这段代码,这是正确的(每次都会给我正确的答案),但是根本没有进入该递归循环。那我可以在这里省略那个电话吗?
def recursiveHalfString(s):
#@param s: string
#@return bool
if (len(s))%2==0: #verify if the rest of the division by 2 = 0 (even number)
if len(s)<=1: # case in which I can use the == operator
if s[0]==s[1]:
return True
else:
return False
if len(s)>1:
if s[0:len(s)/2] != s[len(s)/2:len(s)]: # here I used != instead of ==
if s!=0:
return False
else:
return recursiveHalfString(s[0:(len(s)/2)-1]+s[(len(s)/2)+1:len(s)]) # broken call
return True
else:
return "Error: odd string"
如果字符串类似于“ abbaabba”,则预期结果为True 或False,就像其他与模式(“ wordword”)不相似的东西一样
答案 0 :(得分:6)
这是一个经过简化的递归版本,实际上使用单个字符比较来减小问题的大小:
def rhs(s):
half, rest = divmod(len(s), 2)
if rest: # odd length
raise ValueError # return 'error'
if half == 0: # simplest base case: empty string
return True
return s[0] == s[half] and rhs(s[1:half] + s[half+1:])
尽管必须说,在算法上,考虑到约束条件,这个问题并不适合于递归方法。
答案 1 :(得分:1)
这是另一种递归解决方案。采取递归方法时,一个好的经验法则是首先考虑您的基本案例。
def recursiveHalfString(s):
# base case, if string is empty
if s == '':
return True
if (len(s))%2==0:
if s[0] != s[(len(s)/2)]:
return False
else:
left = s[1:len(s)/2] # the left half of the string without first char
right = s[(len(s)/2)+1: len(s)] # the right half without first char
return recursiveHalfString(left + right)
else:
return "Error: odd string"
print(recursiveHalfString('abbaabba')) # True
print(recursiveHalfString('fail')) # False
print(recursiveHalfString('oddstring')) # Error: odd string
此函数将字符串分成两半,比较第一个字符,并以串联在一起的两半(不带前导字符)的方式递归调用自身。
但是,就像在另一个答案中所述,在这种情况下,递归不一定是有效的解决方案。这种方法会创建许多新的字符串,绝不是实现此目的的最佳方法。它仅用于演示目的。
答案 2 :(得分:1)
另一种不涉及创建新字符串的递归解决方案可能看起来像:
def recursiveHalfString(s, offset=0):
half, odd = divmod(len(s), 2)
assert(not odd)
if not s or offset > half:
return True
if s[offset] != s[half + offset]:
return False
return recursiveHalfString(s, offset + 1)
但是,正如@schwobaseggl所建议的,这里的递归方法比简单的迭代方法要笨拙:
def recursiveHalfString(s, offset=0):
half, odd = divmod(len(s), 2)
assert(not odd)
for offset in range(half):
if s[offset] != s[half + offset]:
return False
return True