給定一個非零長度的字串化電話號碼,撰寫一個函式以任意順序回傳此電話號碼的所有助記符。
`
def phoneNumberMnemonics(phoneNumber, Mnemonics=[''], idx=0):
number_lookup={'0':['0'], '1':['1'], '2':['a','b','c'], '3':['d','e','f'], '4':['g','h','i'], '5':['j','k','l'], '6':['m','n','o'], '7':['p','q','r','s'], '8':['t','u','v'], '9':['w','x','y','z']}
if idx==len(phoneNumber):
return Mnemonics
else:
new_Mnemonics=[]
for letter in number_lookup[phoneNumber[idx]]:
for mnemonic in Mnemonics:
new_Mnemonics.append(mnemonic letter)
phoneNumberMnemonics(phoneNumber, new_Mnemonics, idx 1)
`
如果我使用輸入“1905”,我的函式輸出 null。在 return 陳述句之前使用 print 陳述句,我可以看到串列 Mnemonics 是
['1w0j', '1x0j', '1y0j', '1z0j', '1w0k', '1x0k', '1y0k', '1z0k', '1w0l', '1x0l', '1y0l', '1z0l']
這是正確的答案。為什么回傳null?
我不太擅長實作遞回(還沒有?),感謝您的幫助。
uj5u.com熱心網友回復:
這個問題有不同的遞回運算式,但是當你開始時最容易想到的是“純函式式”。這意味著您永遠不會改變遞回確定的值。而是計算新的值:串列等(Python 沒有給你關于字串的選擇;它們總是不可變的。)通過這種方式,你可以只考慮值,而不是它們的存盤方式和改變它們的原因,這非常容易出錯。
考慮這個問題的純函式式方法是:
如果電話號碼是空字串,則回傳值只是一個包含空字串的串列。
否則將數字分解為第一個字符和其余字符。遞回得到其余所有的助記符R。然后找到與第一個相對應的所有字母,并將每個字母添加到 R 的每個成員中以創建一個新字串(這稱為笛卡爾叉積,它經常在遞回中出現。)回傳所有這些字串。
在這個運算式中,純函式的形式為
M(n: str) -> list[str]:
它接受一串數字并回傳助記符串列。
把這個想法放到 python 中是相當簡單的:
LETTERS_BY_DIGIT = {
'0':['0'],
'1':['1'],
'2':['a','b','c'],
'3':['d','e','f'],
'4':['g','h','i'],
'5':['j','k','l'],
'6':['m','n','o'],
'7':['p','q','r','s'],
'8':['t','u','v'],
'9':['w','x','y','z'],
}
def mneumonics(n: str):
if len(n) == 0:
return ['']
rest = mneumonics(n[1:])
first = LETTERS_BY_DIGIT[n[0]]
rtn = [] # A fresh list to return.
for f in first: # Cartesian cross:
for r in rest: # first X rest
rtn.append(f r); # Fresh string
return rtn
print(mneumonics('1905'))
請注意,此代碼根本不會改變遞回回傳??值rest。它創建了一個新字串的新串列。
當你掌握了所有的 Python 習語后,你會看到一種更巧妙的方式來撰寫相同的代碼:
def mneumonics(n: str):
return [''] if len(n) == 0 else [
c r for c in LETTERS_BY_DIGIT[n[0]] for r in mneumonics(n[1:])]
這是解決這個問題最有效的代碼嗎?絕對不。但這無論如何都不是一件很實際的事情。在您牢牢掌握這種思維方式之前,最好選擇一個簡單、正確且易于理解的解決方案,而不是擔心效率。
正如其他人所說,如果這是生產要求,那么在這個問題上使用遞回并不是一個很好的選擇。
uj5u.com熱心網友回復:
為最深的遞回呼叫生成了正確的串列(助記符)。但是,它沒有傳遞回之前的呼叫。
為了解決這個問題,不僅需要在“else”塊中回傳助記符,還需要將其設定為等于遞回函式 phone Number Mnemonics 的輸出。
def phoneNumberMnemonics(phoneNumber, Mnemonics=[''], idx=0):
number_lookup={'0':['0'], '1':['1'], '2':['a','b','c'], '3':['d','e','f'], '4':['g','h','i'], '5':['j','k','l'], '6':['m','n','o'], '7':['p','q','r','s'], '8':['t','u','v'], '9':['w','x','y','z']}
print(idx, len(phoneNumber))
if idx==len(phoneNumber):
pass
else:
new_Mnemonics=[]
for letter in number_lookup[phoneNumber[idx]]:
for mnemonic in Mnemonics:
new_Mnemonics.append(mnemonic letter)
Mnemonics=phoneNumberMnemonics(phoneNumber, new_Mnemonics, idx 1)
return Mnemonics
我仍然覺得我對遞回的理解不夠成熟。歡迎提供建議、反饋和澄清。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/527156.html
上一篇:嘗試撰寫記憶裝飾器時出現遞回錯誤
