【问题标题】:How to generate a list of all possible alphabetical combinations based on an input of numbers如何根据输入的数字生成所有可能的字母组合列表
【发布时间】:2013-04-24 05:21:04
【问题描述】:

我刚刚遇到了一个有趣的面试风格类型的问题,我无法理解。

基本上,给定一个数字到字母表的映射,例如[1:A, 2:B, 3:C ...],打印出所有可能的组合。

例如“123”将生成[ABC, LC, AW],因为它可以分为12,3 和1,23。

我认为它必须是某种类型的递归函数,它检查大小为 1 和 2 的窗口,如果它是有效的字母映射,则附加到先前的结果。

如果有人能制定一些伪/python 代码,将不胜感激。

【问题讨论】:

  • 单独123 怎么样?
  • 是的,那是 ABC,我没有把它包括在内,因为我认为它是给定的,但我会编辑它。
  • 不,是ABC
  • 不,因为它需要考虑整个输入。除非您说的是“1”、“2”、“3”而不是“123”的单独输入
  • 更加有力地定义分离(),并请解释如果 12 是“L”,那么输入“12”的完整答案是什么。它会包括“U”吗?

标签: python algorithm alphabetical


【解决方案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

【讨论】:

  • 在尝试将代码复制粘贴到 stackoverflow 时也存在一些缩进问题
【解决方案2】:

像一棵树一样简单

假设你给了“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

所以一旦你完成了树的构建,只需打印从根到节点的所有路径

这是你的要求。

【讨论】:

    【解决方案3】:
    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))
    

    未经测试,但我相信这符合您的要求。

    【讨论】:

    • 不起作用...检查results.join部分...顺便说一下,这是Python而不是C/C++或VB,关注PEP-8
    • 是的,不会运行,我认为您不必加入,+= 不会起作用吗?不过感谢您的代码,我会尝试解析逻辑并将其合并到我自己的解决方案中。
    • Schoolboy,不要简单地引用标准,还请说明我的约定有什么问题。我现在正在下载 python 来调试它。
    • @Montycarlo 嗯.. 这不是 Pythonic! :)
    • 过于简单化了?抱歉,您无法解释我的代码。
    【解决方案4】:

    以下答案递归地尝试当前位置的所有可能性(不止两个!)并继续字符串的其余部分。就是这样。

    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']) 提供了正确的输出。 (我认为其他一些解决方案不能正确处理零。)

    【讨论】:

      【解决方案5】:

      所以,我也想解决这个问题,因为这实际上是一个很酷的问题。所以这是我的解决方案:

      如果我们暂时忽略对字符串的翻译,我们实际上是在寻找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']
      

      【讨论】:

      • 很好,这是一种非常有趣和 Python 式的解决问题的方法!
      【解决方案6】:

      我仍然不确定描述,但是这个 Python 脚本首先将 num 划分为它的“breaks”,然后尝试将每个 break 成员作为一个整体作为其对应字符的索引;然后将成员的每个数字转换为单词的字母。在显示所有转换为字母/单词的数字“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']
      >>> 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-29
        • 2012-12-03
        • 1970-01-01
        • 2022-12-06
        • 1970-01-01
        • 1970-01-01
        • 2014-10-22
        相关资源
        最近更新 更多