【问题标题】:Generate numbers from a set of digits从一组数字生成数字
【发布时间】:2016-08-25 09:42:02
【问题描述】:

我正在尝试从一组数字中生成三个数字的所有可能组合。
假设我有 1 到 9 的数字(每个一次),我想生成三个数字,例如 14, 983, 7256(但所有可能的组合)。所以每个数字只能使用一次,所有数字都必须使用。

我的第一个想法是为每个数字生成不同的数字集作为一个池,如下所示:

bin_arr = []
for i in range(1, 512):
    bin_arr.append([int(a) for a in ("{0:0b}".format(i))])

>>> bin_arr[257]
>>> [1, 0, 0, 0, 0, 0, 0, 0, 1]

compress 这些和'123456789' 但似乎没有去任何地方。

有没有办法巧妙地做到这一点?

【问题讨论】:

  • 顺序重要吗? [14, 983, 7256][983, 14, 7256] 有区别吗?
  • 是的。最后,顺序确实很重要。但如果我有所有三倍,我可以在之后做到这一点。但如果你能够在生成三元组的同时做到这一点,那就更好了。

标签: python numbers


【解决方案1】:

我们可以假设像 [14,983,2567] 这样的一个列表是一个数字序列 149832567,然后我们添加两个逗号,一个在 4 之后,另一个在 3 之后,因此我们生成了三个数字 [14,983,2567] .

那么,可以生成多少个数列呢?

In [1]: import itertools

In [2]: a = range(1,10)

In [3]: a
Out[3]: [1, 2, 3, 4, 5, 6, 7, 8, 9]

In [4]: len(list(itertools.permutations(a,9)))
Out[4]: 362880

当我们得到一个像437865192这样的数列时,可以生成多少个三元数?组合

8*7/2 = 28(在 9 个数字之间选两个空格)

或使用itertools.combinations

In [8]: len(list(itertools.combinations(list(range(8)),2)))
Out[8]: 28

给定一个序列,我们将得到 28 种组合。

In [1]: a = ['2','3','6','4','9','1','7','8','5']

In [2]: import itertools

In [4]: for i in itertools.combinations(range(1,9),2):
...:     print [int(''.join(a[:i[0]])), int(''.join(a[i[0]:i[1]])), int(''.join(a[i[1]:]))]

[2, 3, 6491785]
[2, 36, 491785]
[2, 364, 91785]
[2, 3649, 1785]
[2, 36491, 785]
[2, 364917, 85]
[2, 3649178, 5]
[23, 6, 491785]
[23, 64, 91785]
[23, 649, 1785]
[23, 6491, 785]
[23, 64917, 85]
[23, 649178, 5]
[236, 4, 91785]
[236, 49, 1785]
[236, 491, 785]
[236, 4917, 85]
[236, 49178, 5]
[2364, 9, 1785]
[2364, 91, 785]
[2364, 917, 85]
[2364, 9178, 5]
[23649, 1, 785]
[23649, 17, 85]
[23649, 178, 5]
[236491, 7, 85]
[236491, 78, 5]
[2364917, 8, 5]

因此将生成 10160640(362880*28) 个列表。

最终代码:

In [15]: a=map(lambda x:str(x), range(1,10))

In [16]: a
Out[16]: ['1', '2', '3', '4', '5', '6', '7', '8', '9']

In [17]: result = []

In [18]: for seq in itertools.permutations(a,9):
    ...:     for i in itertools.combinations(range(1,9),2):
    ...:         result.append([int(''.join(seq[:i[0]])), int(''.join(seq[i[0]:i[1]])), int(''.join(seq[i[1]:]))])
    ...:

In [19]: len(result)
Out[19]: 10160640

【讨论】:

  • 但不幸的是它不起作用。 result 中的列表已排序。所以它始终是原始序列a,其中有两个分隔符。您在第 1 步中所做的排列不知何故丢失了。
  • @span class="comcopy">@sorry,最后一个追加,我把seq误认为是原来的a,所以是错误的。现在看我的更新。
【解决方案2】:

假设顺序很重要,我会这样做:

@ results 是所需选项的列表,例如如果您想要一个数字为 0-9 的数字,请使用输出 [0,1, . . ., 9].

@length 是每个输出数字的位数。您在问题中最多使用了 4 位数字,我假设有一些上限。

使用下面的函数为三元组的每个单独部分生成排列,然后将结果反馈回以生成进一步的排列。

def gen_permutations(outcomes, length):
        ans = set([()])
        for dummy_idx in range(length):
            temp = set()
            for seq in ans: 
                for item in outcomes: #each possible outcome
                    new_seq = list(seq)
                    if len(outcomes) == 1 or item in new_seq:
                        continue
                    new_seq.append(item)
                    temp.add(tuple(new_seq))
            ans = temp

        return ans

【讨论】:

  • 每个数字没有上限。只是总是必须有三个,每个数字只能使用一次。所以(1, 2, 3456789) 也是一个有效的三元组。此外,您的功能没有做它应该做的事情。它只是给我一个给定长度和提供数字的排列列表。
猜你喜欢
  • 2017-02-16
  • 1970-01-01
  • 2014-05-13
  • 2012-08-16
  • 1970-01-01
  • 1970-01-01
  • 2018-05-20
  • 2017-12-09
相关资源
最近更新 更多