我生成了一组n元素数组,它由交替的1和-1组成,后面跟着0,都以1开头。
例如,对于n=5,数组是: 10000,1-1000,1-1100,1-11-10,1-11-11,
我需要“插入”每个数组的非零数字之间的零:在上面的示例中,对于1-1100,枚举是:
1 -1 10 0,(允许1和-1之间没有0)
1-10 10,
10-10 10,
10-10 0 1,
10 0 -1 1,
1 -1 0 0 1(第一个元素仍然需要1)
对于具有上述格式的给定数组,是否有一个很好的算法来生成这样的枚举?
我认为这个问题就像把相同的苹果放在不同的盘子里(因为把零放进不同的间隙会产生不同的计数),并且允许一些盘子保持空。
我需要把所有的可能性都打印出来,而不仅仅是数数。但目前我还想不出一个好办法。
发布于 2014-06-27 21:54:53
这比看上去简单多了。
第一个元素总是1,因此,我们可以忽略这一点,只需将1放在我们回答的前面。
初始1之后的非零元素总是-1,1,-1等。由于这个模式是固定的,我们可以用1替换所有的非零,然后再翻译回来。
所以现在我们有一个0和1的列表,需要生成它们的所有排列。
在Python中将所有内容组合在一起:
#!/usr/bin/env python3
N = 5
def main():
# k = number of nonzeros, minus the initial one that's always there
for k in range(N):
seq = [0] * (N - 1 - k) + [1] * k
for p in next_permutation(seq):
result = decorate(p)
print(" ".join("{:2d}".format(i) for i in result))
# adapted from http://stackoverflow.com/questions/4250125
def next_permutation(seq):
seq = seq[:]
first = 0
last = len(seq)
yield seq
if last == 1:
raise StopIteration
while True:
next = last - 1
while True:
next1 = next
next -= 1
if seq[next] < seq[next1]:
mid = last - 1
while seq[next] >= seq[mid]:
mid -= 1
seq[next], seq[mid] = seq[mid], seq[next]
seq = seq[:next1] + list(reversed(seq[next1:last])) + seq[last:]
yield seq[:]
break
if next == first:
raise StopIteration
raise StopIteration
def decorate(seq):
# Convert 1's to alternating -1, 1, then prepend a 1 to whole thing
seq = seq[:]
n = -1
for i in range(len(seq)):
if seq[i]:
seq[i] = n
n = -n
return [1] + seq
main()https://stackoverflow.com/questions/24459227
复制相似问题