带重复的数字全排列

0 投票
8 回答
1639 浏览
提问于 2025-04-17 23:14

我想生成一个长度为4的向量,里面包含0、1、2的所有可能组合。组合的顺序不重要,比如11000101, 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

撰写回答