我刚刚遇到一个有趣的采访风格类型的问题,我无法理解。
基本上,给定一个字母到数字的映射[1:A, 2:B, 3:C ...]
,打印出所有可能的组合。
例如,“123”将生成[ABC, LC, AW]
,因为它可以分为12,3和1,23。
我认为它必须是某种类型的递归函数,它检查大小为1和2的窗口,如果它是有效的字母映射,则附加到前一个结果。
如果有人能够制定一些非常受欢迎的伪/ python代码。
答案 0 :(得分:1)
像树一样简单
假设你给了“1261”
用树构建一棵树。
通过定义节点(左,右),其中左侧始终是直接映射,右侧是组合
版本假设您将给定的数字视为1261
1261 - >
(1(261),12(61)) - > 1是左节点(直接映射 - > a)12是右节点(combo-map1,2-> L)
(A(261),L(61)) - >
(A(2(61),26(1))),L(6(1)) - >
(A(B(6(1)),Z(1)),L(F(1))) - >
(A(B(F(1)),Z(A)),L(F(A))) - >
(A(B(F(A)),Z(A)),L(F(A)))
所以现在你已经拥有了所有叶子节点..
只打印从根节点到叶节点的所有路径,这为您提供了所有可能的组合。
就像在这种情况下
ABFA,AZA,LFA
因此,一旦完成了树的构造,只需打印从根到节点的所有路径
这是你的要求。
答案 1 :(得分:1)
所以我设法破解了一个答案,它不像我想的那样具有pythonic并且可能有一些冗余,但它适用于123示例输出ABC,AW和LC。
我明天可能会清理它(或者如果有人想要清理它),只需发布它以防有人也正在处理它并且想知道。
def num_to_alphabet(numbers, ans = ""):
if not numbers:
print ans
numbers = str(numbers)
window = numbers[:2]
alph = string.uppercase
ans = ans[:]
ans2 = ans[:]
window_val = ""
try:
if window[0]:
val = int(numbers[0])-1
if alph[val]:
ans += alph[val]
num_to_alphabet(numbers[1:], ans)
if window[1]:
val = int(window) -1
if alph[val]:
ans2 += alph[val]
if len(window) > 1:
num_to_alphabet(numbers[2:],ans2)
else:
num_to_alphabet(numbers[1:],ans2)
except IndexError:
pass
答案 2 :(得分:0)
charMap = {'1':'A', '2':'B' ... }
def getNodes(str):
results = []
if len(str) == 0: return results
c = str[0]
results.append(c)
results = results.join(c.join(getNodes(str[1:])))
if str[:2] in charMap.keys(): results = results.join(c.join(getNodes(str[2:])))
return results
def mapout(nodes):
cArray = []
for x in nodes:
cx = ''
for y in x:
cx = cx + charMap.get(y)
cArray.append(cx)
return cArray
res = getNodes('12345')
print(mapout(res))
未经测试,但我相信这与您所寻找的一致。
答案 3 :(得分:0)
以下答案以递归方式尝试当前位置的所有可能性(有两个以上!)并继续使用字符串的其余部分。就是这样。
from string import ascii_uppercase
def alpha_combinations(s):
if len(s) == 0:
yield ""
return
for size in range(1, len(s) + 1):
v = int(s[:size])
if v > 26:
break
if v > 0:
c = ascii_uppercase[v - 1]
for ac in alpha_combinations(s[size:]):
yield c + ac
print(list(alpha_combinations(input())))
它期望一个数字作为字符串。它为101010
(['AAJ', 'AJJ', 'JAJ', 'JJJ']
)提供了正确的输出。 (我认为其他一些解决方案无法正确处理零。)
答案 4 :(得分:0)
所以,我也想解决这个问题,因为它实际上是一个很酷的问题。所以这是我的解决方案:
如果我们暂时忽略对字符串的翻译,我们基本上是在寻找partitions of a set。因此,对于输入123
,我们有一个集{1, 2, 3}
并且正在寻找分区。但是在那些分区中,只有那些保持原始输入顺序的有趣。所以我们实际上并没有谈论最后的一个集合(顺序无关紧要)。
无论如何,我称之为“有序分区” - 我不知道是否确实存在一个术语。我们可以使用递归轻松生成这些有序分区:
def orderedPartitions(s):
if len(s) == 0:
yield []
return
for i in range(1, len(s)+1):
for p in orderedPartitions(s[i:]):
yield [s[:i]] + p
对于字符串输入'123'
,这给了我们以下部分,这正是我们正在寻找的:
['1', '2', '3']
['1', '23']
['12', '3']
['123']
现在,为了回到原来要求翻译成字符串的问题,我们需要做的就是检查每个分区,如果它们只包含有效数字,即1到26.如果是这样的话,翻译这些数字并返回结果字符串。
import string
def alphaCombinations(s):
for partition in orderedPartitions(str(s)):
# get the numbers
p = list(map(int, partition))
# skip invalid numbers
if list(filter(lambda x: x < 1 or x > 26, p)):
continue
# yield translated string
yield ''.join(map(lambda i: string.ascii_uppercase[i - 1], p))
它有效:
>>> list(alphaCombinations(123))
['ABC', 'AW', 'LC']
>>> list(alphaCombinations(1234))
['ABCD', 'AWD', 'LCD']
>>> list(alphaCombinations(4567))
['DEFG']
答案 5 :(得分:0)
我仍然不确定描述,但是这个Python脚本首先将num分区为其'break',然后将每个break成员作为一个整体尝试作为其相应字符的索引;然后将成员的每个数字转换为单词的字母。在显示所有转换为num“123”的字母/单词的总和之前显示两个贡献
>>> import string
>>> mapping ={str(n):ch for n,ch in zip(range(1,27), string.ascii_uppercase)}
>>> num = '123'
>>> [[num[:i], num[i:]] for i in range(len(num)+1)]
[['', '123'], ['1', '23'], ['12', '3'], ['123', '']]
>>> breaks = set(part for part in sum(([num[:i], num[i:]] for i in range(len(num)+1)), []) if part)
>>> breaks
{'123', '12', '3', '1', '23'}
>>> as_a_whole = [mapping[p] for p in breaks if p in mapping]
>>> as_a_whole
['L', 'C', 'A', 'W']
>>> by_char = [''.join(mapping[n] for n in p) for p in breaks]
>>> by_char
['ABC', 'AB', 'C', 'A', 'BC']
>>> everything = sorted(set(as_a_whole + by_char))
>>> everything
['A', 'AB', 'ABC', 'BC', 'C', 'L', 'W']
>>>