置换所有可能的(0,1)值数组

时间:2010-09-17 12:09:10

标签: c++ algorithm

我正在编写一个算法来生成这种数组的所有可能的排列:

n =长度
k =数组中1的数字

所以这意味着如果我们有k 1,我们将在数组中得到n-k 0。

例如: n = 5; k = 3;

因此,显然有5个选择3个可能的排列因为这个数组 N!/(K!(N-K)!
5!/(3!2!)=(5 * 4)/ 2 = 10
数组的可能值

以下是所有值:
11100个
11010个
11001个
10110个
10101个
10011个
01110
01101
01011
00111

我猜我应该使用递归算法,但我只是没有看到它。我正在用C ++编写这个算法。

任何帮助将不胜感激!

7 个答案:

答案 0 :(得分:8)

00111开始,然后使用std::next_permutation生成其余内容:

#include <algorithm>
#include <iostream>
#include <string>

int main()
{
    std::string s = "00111";
    do
    {
        std::cout << s << '\n';
    }
    while (std::next_permutation(s.begin(), s.end()));
}

输出:

00111
01011
01101
01110
10011
10101
10110
11001
11010
11100

答案 1 :(得分:5)

您可以将组合分为以1(n-1,k-1)开头的组合和以0(n-1,k)开头的组合。

这基本上是recursive formula for the choose function

答案 2 :(得分:2)

如果要以递归方式执行此操作,请观察所需的排列集等于所有以"1"开头的排列,以及所有以"0"开头的排列。因此,在计算(n,k)时,您将对(n-1,k-1)(n-1,k)进行递归,特殊情况为k = 0k = n

这种递归是二项式系数显示为Pascal三角形值的原因。

答案 3 :(得分:2)

你想要的实际上是一个组合,因为1和0是无法区分的,因此它们的顺序无关紧要(例如 1 1 1 vs 1 1 1 )。

我最近不得不自己重写一个组合函数,因为我的初始版本是以非常简单的方式递归编写的(选择一个元素,获取剩余数组的所有组合,在不同的地方插入元素)并且执行得不是很好好。

我搜索了StackOverflow,只是看到this answer中的图片点亮了我头上的标志性灯泡。

答案 4 :(得分:1)

家庭作业和递归算法?好的,你走了:

基本情况: 你有两个元素,命名为“a”和“b”并产生连接ab,然后是ba。

步骤:如果您的第二个元素长于1,请将其拆分为第一个字段/字母和另一个部分,然后将该递归作为参数传递给函数本身。

这适用于任何字符串和数组。

答案 5 :(得分:1)

它的大约0-1排列,因此可能更有效地迭代递增一个整数,如果它有所需的位数,则打印出它的二进制表示。

这是草图:

void printAllBinaryPermutations(int k, int n)  
{  
  int max = pow(2, n) - 1;  
  for(int i=0; i<=max;i++)  
  {  
    if(hasBitCountOf(i, k)) // i has k 1's?  
    {  
      printAsBinary(i, n);  
    }  
  }  
}  


bool hasBitCountOf(int v, int expectedBitCount)  
{  
    int count = 0;  
    while(v>0 && count<= expectedBitCount)  
    {  
        int half = v >> 1;  
        if(half<<1 != v)  
        {  
            // v is odd  
            count++;  
        }  
        v = half;  
    }  

    return count==expectedBitCount;  
}  


void printAsBinary(int number, int strLen)  
{  
  for(int i=strLen-1; i>=0; i--)  
  {  
    bool is0 = (number & pow(2,i)) == 0;  
    if (is0)  
    {  
      cout<<'0';  
    }  
    else  
    {  
      cout<<'1';  
    }  
  }   

  cout<<endl;  

}

答案 6 :(得分:0)

我不确定这会有什么帮助,而且它只是一些奇怪的伪代码,但这应该会给你所需的输出。

permutation (prefix, ones, zeros, cur) {
    if (ones + zeros == 0) output(cur);
    else {
        if (cur != -1) prefix = concat(prefix,cur);
        if (ones > 0) permutation(prefix, ones - 1, zeros, 1);
        if (zeros > 0) permutation(prefix, ones, zeros - 1, 0);
    }        
}

permutation(empty, 3, 2, -1);

格尔茨
back2dos