假设我有一个包含5个元素的数组。如何在C中计算此数组的所有可能的重复排列。
编辑:我的意思是使用该5号码创建所有可能的数组。所以这个位置很重要。
示例:
array = [1,2,3,4,5]
[1,1,1,1,1]
[1,1,1,1,2]
[1,1,1,2,3]
.
.
答案 0 :(得分:4)
生成组合或排列的常用方法是使用递归:枚举第一个元素的每种可能性,并将其添加到由一个元素减少的同一组的每个组合或排列中。所以,如果我们说你一直在寻找 n 事物的排列数 k ,我们使用符号perms( n , k ),你得到:
perms(5,5) = {
[1, perms(5,4)]
[2, perms(5,4)]
[3, perms(5,4)]
[4, perms(5,4)]
[5, perms(5,4)]
}
同样,对于烫发(5,4),你得到:
perms(5,4) = {
[1, perms(5,3)]
[2, perms(5,3)]
[3, perms(5,3)]
[4, perms(5,3)]
[5, perms(5,3)]
}
部分电影(5,5)看起来像是:
[1, 1, perms(5,3)]
[1, 2, perms(5,3)]
[1, 3, perms(5,3)]
[1, 4, perms(5,3)]
[1, 5, perms(5,3)]
[2, 1, perms(5,3)]
[2, 2, perms(5,3)]
...
定义权限( n , k )很简单。对于任何递归定义,您需要两件事:基本案例和递归步骤。基本情况是 k = 0:perms( n ,0)是一个空数组,[]。对于递归步骤,您可以通过将集合中的每个可能值添加到perms的所有元素( n , k -1)来生成元素。
答案 1 :(得分:3)
如果我正确地得到您的问题,您需要生成所有包含数字1,2,3,4和5的5位数字。因此,有一个简单的解决方案 - 生成所有数字基数为5到44444
和然后将0映射到1,1到2,依此类推。在需要时添加前导零 - 因此10
变为00010
或[1,1,1,2,1]
。
注意:你实际上 没有自己生成数字,你可能只需要将数字重复到5 ** 5(不包括),并且每个数字都可以通过获取相应的序列来查找相应的序列这是数字基数5.
答案 2 :(得分:2)
在您给出的示例中,每个职位都可以由1
,2
,3
,4
,5
占用。由于有5个职位,可能性总数= 5 * 5 * 5 * 5 * 5 = 5 ^ 5 = 3125
。一般来说,它是N ^ N
。 (其中^是取幂运算符)。
要生成这些可能性,请在每个位置中逐个输入数字1
,2
,3
,4
,5
,从最后一个位置开始递增,类似于5位计数器。
因此,从11111
开始。增加最后一个位置以获得11112
...直到11115
。
然后回到1
,然后使用11121
... 11122
继续递增下一个数字11125
,等等。重复此操作,直至到达第一个位置,然后你会在55555
结束。
答案 3 :(得分:2)
int increment(size_t *dst, size_t len, size_t base) {
if (len == 0) return 0;
if (dst[len-1] != base-1) {
++dst[len-1];
return 1;
} else {
dst[len-1] = 0;
return increment(dst, len-1, base);
}
}
使用此函数,您可以从{0, 0, 0, 0, 0}
开始迭代(0 ... 4)的所有重复排列。当重复排列用完时,该函数将返回0。
然后对于每个重复排列依次使用内容作为数组的索引,以获得数组的重复排列而不是(0 ... 4)。