[英]Recursive function in python does not call itself out
問題的表述如下:
編寫一個遞歸函數,給定一個字符串,檢查字符串是否由彼此相等的兩半組成(即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,或者當它與其他模式(“wordword”)不相似時為False
這是一個非常簡化的遞歸版本,它實際上使用單個char比較來減少問題大小:
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:])
必須要說的是,在算法上,考慮到約束,這個問題不適合遞歸方法。
這是另一種遞歸解決方案。 采用遞歸方法時,一個好的經驗法則是首先考慮你的基本情況 。
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
此函數將字符串分成兩半,比較第一個字符並遞歸調用自身,兩個連接在一起而沒有前導字符。
但是,如另一個答案中所述,遞歸在這種情況下不一定是有效的解決方案。 這種方法創建了許多新字符串,絕不是最佳方法。 它僅用於演示目的。
另一個不涉及創建一堆新字符串的遞歸解決方案可能如下所示:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.