是否有类似 next_permutation 的函数,但用于重复排列?

Posted

技术标签:

【中文标题】是否有类似 next_permutation 的函数,但用于重复排列?【英文标题】:Is there a function like next_permutation but for permutations with repetition? 【发布时间】:2012-04-08 21:28:01 【问题描述】:

我想做的是找到一维数组的每个排列及其内容的重复。

例如

int array[]=1,2,3;
for(i=0;i<3;i++)
    next_permutation(array,array+3)
    for(int j=0;j<=3;j++)
        printf("%d ",array[j]);
    
printf("\n");

将返回:

1 2 3
1 3 2
2 1 3
etc...

我希望函数返回什么:

1 1 1
1 1 2
1 2 1
2 1 1
1 2 2
2 2 1
2 1 2
1 1 3
1 3 1
3 1 1
etc...

有没有可以做到这一点的函数?

提前致谢, 埃里克

【问题讨论】:

这是相关的:***.com/questions/1944508/arbitrary-digit-counter 还有这个:***.com/questions/2380962/… 【参考方案1】:

你不是在做排列,只是在计数。

例如。如果您的枚举集 0, 1 超过 3 位,您将得到:

000
001
010
011
100
101
110
111

看,这只是二进制计数。

因此,将您的元素集映射为 n 位,然后基于 n 进行计数将为您提供正确的 awnser

【讨论】:

【参考方案2】:

这是我用 Java 编写的。 未优化的代码,但你明白了:

String [] data = "1","2","3";
public void perm(int maxLength, StringBuffer crtComb)

    if (crtComb.length() == maxLength)
        System.out.println(crtComb.toString());
        return;
    

    for (int i=0; i<data.length; i++)
        crtComb.append(data[i]);
        perm(maxLength, crtComb);
        crtComb.setLength(crtComb.length()-1);
    


【讨论】:

【参考方案3】:

通常在计算从 1 到 k 的整数排列时(重复):

    最初将第一个排列设置为 1 1 1 ....(k 次)。

    找到最右边的索引(比如 j),使得该索引处的元素小于 k。

    将索引 j 处元素的值加一,从位置 j + 1 到 k 将所有元素重置为 1。

    重复步骤 2 和 3。

应用这个逻辑,我们现在得到:

第一个排列 -> 1 1 1.

然后在位置 2(0 索引计数),我们有 1 1 1 2。

然后在位置 1(0 索引计数),我们有 1 1 2 1

等等。

【讨论】:

以上是关于是否有类似 next_permutation 的函数,但用于重复排列?的主要内容,如果未能解决你的问题,请参考以下文章

排列组合函数next_permutation()

[OI - STL] next_permutation( ) & prev_permutation( )函数

幂集中组合或子集的 next_permutation

STL next_permutation 算法原理和自行实现

STL next_permutation 算法原理和自行实现

STL next_permutation排列