在c ++中生成排列的递归问题

时间:2011-12-24 17:56:02

标签: c++ recursion permutation recurrence

我在c ++中有两个n并且我想以这种方式生成这些向量中的数字的排列,对于第一个向量的每个排列,我具有所有其他向量的所有排列。 假设我有两个向量,数字为2 9,另一个向量为5 6.那么我的结果应该是......

  1. 2 9 5 6
  2. 2 9 6 5
  3. 9 2 5 6
  4. 9 2 6 5
  5. 表示我获得的排列总数将是 总perms =(第一个向量的排列数乘以第二个向量的排列数乘以第三个向量的排列数等等)。

    我已经编写了下面的代码,我对递归堆栈感到震惊......实际上,对于2个向量,每个大小为2的情况,打印6次。

    mySwap(int *x, int *y){
    int temp;
    temp = *x;
        *x = *y;
    *y = temp;
    }
    

    交换两个int元素

    void myPerm(vector<vector<int>> myItems, int start, int end,int     vectorIndex){
    int j;
    if(start == end){
        for(int k = vectorIndex +1; k < items.size(); ++k){
            myPerm(myItems, 0, myItems[k].size()-1,k);
        }
        for(int z = 0; z < myItems.size(); ++z){
            for(int l = 0; l < myItems[z].size(); ++z){
                std::cout << myItems[z][l];
            }
        }
    }
    else{
        for(int j = start; j <= end; j++){
            mySwap(&myItems[vectorIndex][start],&myItems[vectorIndex][j]);
            myPerm(myItems,start + 1, end,vectorIndex);
            mySwap(&myItems[vectorIndex][start],&myItems[vectorIndex][j]);
    
        }   
    
    }
    } 
    

    以上代码以递归方式生成排列...

    int main(){
    vector<vector<int>> myItems;
    int k = 0;
    for(int i =0; i < 2; ++i){
        myItems.push_back(vector<int>);
    }
    for(int j =0; j < 2; ++j){
        myItems[i].push_back(k++);
    }
    
    myPerm(items,0,items[0].size()-1,0);
    return;
    }
    

    我的主要功能。

    请给我一些提示或解决这个问题,因为上面的代码打印了六个最初应该是4次的排列。

    由于

3 个答案:

答案 0 :(得分:0)

考虑到这不是一个功课,你可以简单地使用stl算法 next_permutation 而不是你拥有的算法。

这是您的示例输入的代码。

int main()
{

    std::vector<int> v1 , v2 , v3;
    v1.push_back( 2 );
    v1.push_back( 9 );
    v2.push_back( 5 );
    v2.push_back( 6 );

    std::sort( v1.begin() , v1.end() );
    std::sort( v2.begin() , v2.end() );

    do 
    {   
        v3 = v2;

        do 
        {
            std::for_each( v1.begin() , v1.end() , [](int x) { std::cout << x << " ";} );
            std::for_each( v3.begin() , v3.end() , [](int x) { std::cout << x << " ";} );
            std::cout << std::endl;
        } 
        while ( std::next_permutation(v3.begin() , v3.end() ) );
    } 
    while ( std::next_permutation(v1.begin() , v1.end() ) );

    return 0;
}

这适用于两个载体......我相信你可以进一步概括它。

答案 1 :(得分:0)

感谢专门针对STL函数next_permutation的所有想法。我不早点知道。

我能够正确地编写我想要的代码......

这是我的代码

void perm(std::vector<std::vector <int>> &items, int level){
if(level == 0){
for (int i = 0; i < items.size(); i++)
  for (int j = 0; j < items[i].size(); j++)
      std::cout << items[i][j];
std::cout<<std::endl;


    while(next_permutation(items[level].begin(), items[level].end())){
        for (int i = 0; i < items.size(); i++)
          for (int j = 0; j < items[i].size(); j++)
              std::cout << items[i][j];
        std::cout<<std::endl;
    }
}
else{

    if(level > 0)
    perm(items,level-1);
    while(next_permutation(items[level].begin(), items[level].end())){
        if(level > 0)
        perm(items,level-1);
    }

}

}

答案 2 :(得分:-1)

对于此问题,可以使用next_permutation完全省略递归。这里有一些未经测试的代码可以说更优雅:

void myPerm(std::vector<std::vector<int>>& myItems)
{
    for (int i = 0; i < myItems.size(); i++)
        std::sort(myItems[i].begin(), myItems[i].end());

    int level;

    do
    {
        printAll(myItems);

        level = myItems.size() - 1;

        while (!next_permutation(myItems[level].begin(), myItems[level].end()))
            level--;
    }
    while (level >= 0);
}

关于next_permutation的好处是它返回false,因为它&#34;包裹&#34;给定集合,因此集合已经排序并准备好进行下一轮排列。