2015-07-05 41 views
2

的位置的數字映射轉換所以給定表示字符的字典中的原始字符串

a = 0, b = 1, ..., z = 25

25既可以是cfz功能。我需要寫一個給定數字的函數,返回數字可能表示的所有可能的「ascii」字符串(上例中爲cfz)。

EDIT:字符串可以是任意長度,而不僅僅是2個字符,因此,如果我傳遞給函數1213它可以是1-2-1-3bcbd),或12-1-3,或12-13,或1-2-13等。

我可以看到這可以通過遞歸來解決,但我不知道如何在通過字符串時實際跟蹤不同的值。有關算法可能是什麼的任何暗示?

PS:這不是作業,這是他們在手機屏幕上向我扔的問題。不用說,它不好:/

回答

1

你確實需要遞歸。

儘管您至少有1位數字,請繼續遞歸。這些案件則是:

  • 沒有數字:返回一個空字符串,函數結束
  • 至少1位:查找字符第一個數字,加遞歸值
  • 至少2個數字:查找字符前2位數字(如果存在),並遞歸其餘的值。

這個分支然後導致多個選項,你需要循環這些併產生結果的產物。這是一臺發電機的辦法更容易:

from string import ascii_lowercase as letters 

def find_words(digits): 
    if not digits: 
     yield '' 
     return 
    first = letters[int(digits[0])] 
    for remainder in find_words(digits[1:]): 
     yield first + remainder 
    if len(digits) > 1 and int(digits[:2]) < 26: 
     firsttwo = letters[int(digits[:2])] 
     for remainder in find_words(digits[2:]): 
      yield firsttwo + remainder 

演示:

>>> from string import ascii_lowercase as letters 
>>> def find_words(digits): 
...  if not digits: 
...   yield '' 
...   return 
...  first = letters[int(digits[0])] 
...  for remainder in find_words(digits[1:]): 
...   yield first + remainder 
...  if len(digits) > 1 and int(digits[:2]) < 26: 
...   firsttwo = letters[int(digits[:2])] 
...   for remainder in find_words(digits[2:]): 
...    yield firsttwo + remainder 
... 
>>> for word in find_words('1213'): 
...  print(word) 
... 
bcbd 
bcn 
bvd 
mbd 
mn 
+0

對不起也許我還沒有清楚,但是我知道如何查找的東西,在一個字典;)最棘手的部分是該字符串可能是任何長度,不只是2個字符,所以如果我傳遞給函數'1213',它可以是'1-2-1-3'('bcbd')或'12-1-3'或'12 -13'或者'1-2-13'等等 - 這就是雜亂無章的地方! – whatnot123

+0

@ whatnot123:對,你確實不清楚;這是手機屏幕尋找的另一件事;如果你能清楚地傳達這些約束。:-P –

+0

大聲笑我從來沒有說過字符串被限制爲2個字符 - 但你認爲從我的例子...但它會是一個電話屏幕的笑話,如果是這樣的話:)無論如何,我編輯原始問題... – whatnot123

2

我認爲,我們可以定義你的映射功能列表查找在string.ascii_lowercase

>>> import string 
>>> f = lambda i: string.ascii_lowercase[i] 
>>> f(0) 
'a' 
>>> f(25) 
'z' 

這個函數的整數分區:

>>> def part_int(s, max_i=len(string.ascii_lowercase)): 
...  if s: 
...   for j in range(1, len(s)+1): 
...    i = int(s[:j]) 
...    if i >= max_i: break 
...    for p in part_int(s[j:], max_i): 
...     yield [i] + p 
...  else: 
...   yield [] 
... 
>>> list(part_int('1258')) 
[[1, 2, 5, 8], [1, 25, 8], [12, 5, 8]] 

您可以使用map()給你的函數映射到這些數字:

>>> def int2str(i): 
...  return map(lambda l: ''.join(map(f, l)), part_int(str(i))) 
... 
>>> list(int2str(25)) 
['cf', 'z'] 
>>> list(int2str(1258)) 
['bcfi', 'bzi', 'mfi'] 
+0

我猜在最壞的情況下,遞歸關係是:'T(n)= T(n-1)+ T(n-2)',因此它是'O(2^n)'。我對麼? – Sait

+0

如果'n'是字符串的長度,並且沒有'if if> = max_i:break'是的,但是該行大大地切斷了搜索樹 – fferri