带重复的数字全排列
我想生成一个长度为4的向量,里面包含0、1、2的所有可能组合。组合的顺序不重要,比如1100
和0101, 0011, 1010
都是一样的,所以我只想选择一个值,比如'1100
'。你能告诉我怎么用Python或Perl来实现吗?
0000
1111
1000
2111
''''
''''
我试过用Python的itertools.product,但得到了很多重复的组合。谢谢!
8 个回答
1
你可以使用 itertools.product()
这个工具,把所有的值放到一个列表里,然后去掉重复的值,只要你没有漏掉什么值。下面是用 list(set(mylist))
来去掉重复值的方法:
>>> values = []
>>> values.append(8)
>>> values.append(9)
>>> values.append(9)
>>> values.append(2)
>>> values.append(8)
>>> values.append(3)
>>> values
[8, 9, 9, 2, 8, 3]
>>> values = list(set(values))
>>> values
[8, 9, 2, 3]
3
在R语言中,你可以这样做:
x <- 0:2
out <- unique(t(apply(
do.call(expand.grid,replicate(4,x,simplify=FALSE)),
1,
sort)))
[,1] [,2] [,3] [,4]
[1,] 0 0 0 0
[2,] 0 0 0 1
[3,] 0 0 0 2
[4,] 0 0 1 1
[5,] 0 0 1 2
[6,] 0 0 2 2
[7,] 0 1 1 1
[8,] 0 1 1 2
[9,] 0 1 2 2
[10,] 0 2 2 2
[11,] 1 1 1 1
[12,] 1 1 1 2
[13,] 1 1 2 2
[14,] 1 2 2 2
[15,] 2 2 2 2
3
一种方法可以是:
for i in range(0, 5):
for j in range (0,5-i):
print '0'*i+'1'*j+'2'*(4-i-j)+'\n'
5
这里有一个使用 Algorithm::Combinatorics 的 Perl 选项:
use strict;
use warnings;
use Algorithm::Combinatorics qw/combinations_with_repetition/;
print "@$_\n" for combinations_with_repetition( [ 0 .. 2 ], 4 );
输出结果:
0 0 0 0
0 0 0 1
0 0 0 2
0 0 1 1
0 0 1 2
0 0 2 2
0 1 1 1
0 1 1 2
0 1 2 2
0 2 2 2
1 1 1 1
1 1 1 2
1 1 2 2
1 2 2 2
2 2 2 2
1
这里有一个用Python写的方法:
from itertools import combinations
def perm(chars, length):
s = ''.join([c * length for c in list(chars)])
combs = combinations(s, length)
combs = [''.join(comb) for comb in combs]
combs = list(set(combs))
combs.sort()
return combs
for x in perm('012', 4):
print x
输出结果:
0000
0001
0002
0011
0012
0022
0111
0112
0122
0222
1111
1112
1122
1222
2222