好的,我已经浏览了一下,我已经找到了解决这个问题的C或python解决方案。我更喜欢python ......虽然它是我较弱的语言(2种非常弱的语言)。
一组数字,例如0 0 1 7 0 0 3 0 0 4
首先,我想到找到所有可能的排列然后去除每个排列的箔条(检查n> 0,!n + 1> 0)然后第一个数字> 0 == 1,第二个#> 0 == 7等等。
然后我停了下来,认为这是愚蠢的,说有12个数字,这会给12个!排列。这大约是500,000,000个排列,我将不得不再次通过它来摆脱糠..假设我有40到50套这些数字套装可以通过,这是一个很好的时间。
有更合乎逻辑的方式吗? 我想到某种方式让python做排列以某种方式考虑这些规则(如果n> 0,n + 1必须== 0)和(n =第一个数字,n2 =第二等)。
一个较小的集合的例子是(不是所有的PERMUTATIONS,但给出了想法):
1,2,3,0,0,0,0,0
等。等等 所以1,2,3是有序的,但“0”只是转移了?
谢谢!
答案 0 :(得分:3)
基本上,您希望通过根据不变量对事物进行分组来减少必须计算的组合数。由于非零数字必须是固定的顺序,所以我们从那开始:
1 2 3
因为它们之间必须有0,所以在
中添加它们 1 0 2 0 3
现在剩下的就是要放置三个0,你需要确定有多少组合给出不同的序列。显然,从这个例子中你可能的位置是:在1之前,在1和2之间,在2和3之间以及在3之后。你有4个位置来决定如何分割剩下的3个0。这是combination problem with repetition,此处的解决方案为(3 + 4 - 1) Choose 3
(即20)。
希望我通过这个示例问题的方式足以让你将其推广到任意序列,所以我将把它作为练习留给读者。
答案 1 :(得分:3)
def find_permutations(l):
n = [e for e in l if e] # Strip zeros.
# Interspace non-zeros with zeros.
m = [j for i in n for j in (i,0)][:-1]
def fill(m):
if len(m) == len(l):
yield tuple(m)
else:
# Recursively fill with zeros.
for i in range(len(m)+1):
for o in fill(m[:i] + [0] + m[i:]):
yield tuple(o)
return sorted(set(fill(m)))
我认为这应该涵盖它。所以例如(在python 3中),你可以这样做:
>>> [print(p) for p in find_permutations([1,2,3,0,0,0,0,0])]
(0, 0, 0, 1, 0, 2, 0, 3)
(0, 0, 1, 0, 0, 2, 0, 3)
(0, 0, 1, 0, 2, 0, 0, 3)
(0, 0, 1, 0, 2, 0, 3, 0)
(0, 1, 0, 0, 0, 2, 0, 3)
(0, 1, 0, 0, 2, 0, 0, 3)
(0, 1, 0, 0, 2, 0, 3, 0)
(0, 1, 0, 2, 0, 0, 0, 3)
(0, 1, 0, 2, 0, 0, 3, 0)
(0, 1, 0, 2, 0, 3, 0, 0)
(1, 0, 0, 0, 0, 2, 0, 3)
(1, 0, 0, 0, 2, 0, 0, 3)
(1, 0, 0, 0, 2, 0, 3, 0)
(1, 0, 0, 2, 0, 0, 0, 3)
(1, 0, 0, 2, 0, 0, 3, 0)
(1, 0, 0, 2, 0, 3, 0, 0)
(1, 0, 2, 0, 0, 0, 0, 3)
(1, 0, 2, 0, 0, 0, 3, 0)
(1, 0, 2, 0, 0, 3, 0, 0)
(1, 0, 2, 0, 3, 0, 0, 0)
这与您的想法相似吗?
编辑:基本上称为fill
的函数是在列表的每个数字之间插入一个零,然后递归。只要在fill
函数中记录了足够的数字(递归生成的数字的列表长度等于原始输入的列表长度),就会返回一个数字元组。
返回时转换为元组的唯一原因是类型必须可以在一个集合中使用,如find_permutations
函数的最后一行所示。 sorted
是为了好。