c++ - 通过选择部分或全部字符生成所有排列的算法

标签 c++ algorithm permutation combinations

我需要通过选择一些元素来生成字符串的所有排列。就像我的字符串是“abc”一样,输出将是 { a,b,c,ab,ba,ac,ca,bc,cb,abc,acb,bac,bca,cab,cba }。

我想到了一个基本算法,在该算法中我生成所有可能的“abc”组合,它们是 {a,b,c,ab,ac,bc,abc},然后对它们进行置换。

那么是否有任何有效的排列算法可以生成所有可能的不同大小的排列。

我为此编写的代码是:

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <map>
    using namespace std;

    int permuteCount = 1;


    int compare (const void * a, const void * b)
    {
      return ( *(char*)a - *(char*)b);
    }

    void permute(char *str, int start, int end)
    {
        // cout<<"before sort : "<<str;

        // cout<<"after sort : "<<str;
          do
         {
               cout<<permuteCount<<")"<<str<<endl;  
               permuteCount++;
         }while( next_permutation(str+start,str+end) );  
    }

void generateAllCombinations( char* str)
{
     int     n, k, i, j, c;
     n = strlen(str);

     map<string,int> combinationMap;

for( k =1; k<=n; k++)
{  
   char tempStr[20];
   int index =0;
   for (i=0; i<(1<<n); i++) {
        index =0;
        for (j=0,c=0; j<32; j++) if (i & (1<<j)) c++;
        if (c == k) {

        for (j=0;j<32; j++) 
            if (i & (1<<j)) 
               tempStr[ index++] = str[j];          
        tempStr[index] = '\0';
        qsort (tempStr, index, sizeof(char), compare);
        if( combinationMap.find(tempStr) == combinationMap.end() )
        {
        //  cout<<"comb : "<<tempStr<<endl;
        //cout<<"unique comb : \n";
            combinationMap[tempStr] = 1; 
            permute(tempStr,0,k);   
        }  /*
        else
        {
            cout<<"duplicated comb : "<<tempStr<<endl;
        }*/
        }
  }


}
}


    int main () {


            char str[20];
            cin>>str;

            generateAllCombinations(str);

           cin>>str;
    }

我需要使用散列来避免相同的组合,所以请让我知道如何让这个算法变得更好。

谢谢, 格格

最佳答案

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

int main() {
  using namespace std;
  string s = "abc";
  do {
    cout << s << '\n'; 
  } while (next_permutation(s.begin(), s.end()));
  return 0;
}

Next_permutation 使用恒定大小,但您可以添加一个循环来处理可变大小。或者只是存储在一个集合中以消除额外的欺骗:

#include <set>

int main() {
  using namespace std;
  string s = "abc";
  set<string> results;
  do {
    for (int n = 1; n <= s.size(); ++n) {
      results.insert(s.substr(0, n));
    }
  } while (next_permutation(s.begin(), s.end()));
  for (set<string>::const_iterator x = results.begin(); x != results.end(); ++x) {
    cout << *x << '\n';
  }
  return 0;
}

关于c++ - 通过选择部分或全部字符生成所有排列的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3844721/

相关文章:

c# - 获取所有只包含数字 x 和数字 y 的数字

algorithm - 在盒子里生成球

c++ - 如何使用openGL绘制要点?(C++)

C++ 套接字 - 从结构数组返回单个地址信息

java - n x n 整数矩阵求最大和的动态规划算法

python - 生成带有约束的大量(可能 30)的排列

c++ - 随机排列

c++ - 是否可以省略 `std::forward` 中的模板参数?

c++ - Qt:检查文件夹中的文件是否已更改

具有动态点的二维最近邻查询算法