Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过选择部分或全部字符生成所有置换的算法_C++_Algorithm_Permutation_Combinations - Fatal编程技术网

C++ 通过选择部分或全部字符生成所有置换的算法

C++ 通过选择部分或全部字符生成所有置换的算法,c++,algorithm,permutation,combinations,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> #includ

我需要通过选择一些元素来生成字符串的所有排列。比如,如果我的字符串是“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;
    }
#包括
#包括
#包括
#包括
使用名称空间std;
int permuteCount=1;
整数比较(常数无效*a,常数无效*b)
{
返回(*(字符*)a-*(字符*)b);
}
无效排列(字符*str,整数开始,整数结束)
{
//不能包含
#包括
#包括
int main(){
使用名称空间std;
字符串s=“abc”;
做{
不能包含
#包括
#包括
int main(){
使用名称空间std;
字符串s=“abc”;
做{

我认为你写程序的速度不会比现在快很多。主要问题是输出大小:它的顺序是
n!*2^n
(子集的数量*一个子集的平均排列数量),对于10个不同字符的字符串来说,它已经是
>10^9

由于STL的
next\u排列
为这些小字符串增加了非常有限的复杂性,因此程序的时间复杂性已经接近
O(输出大小)


但是你可以让你的程序简单一点。特别是,
for(k=1;k我认为你写的程序不会比你已经写的快很多。主要问题是输出大小:它的顺序是
n!*2^n
(子集数*一个子集的平均排列数),对于由10个不同字符组成的字符串,它已经是
>10^9

由于STL的
next\u排列
为这些小字符串增加了非常有限的复杂性,因此程序的时间复杂性已经接近
O(输出大小)



但是你可以让你的程序简单一点。特别是,
for(k=1;kI)没有读你的代码,但是你的口头描述听起来是正确的:使用[和置换一起使用。要枚举幂集,可以考虑增加一个二进制数,其中每个“数字”对应于选择输入元素在输出中出现的次数。对于输入集中的重复元素,“二进制”的某些“数字”数字将变为三元数,或该元素的重复计数。请注意,对于长度
N
的字符串,在最坏的情况下(如果所有字符都不同),您将有
2^N-1
不同的非空子集对于由
L
字符组成的每个子集,您将有
L!
排列。我没有读您的代码,但您的口头描述听起来是正确的:将[与排列一起使用。要枚举幂集,请考虑增加一个二进制数,其中每个“数字”对应于选择输入元素在输出中出现的次数。对于输入集中的重复元素,“二进制”的某些“数字”数字将变为三元数,或该元素的重复计数。请注意,对于长度
N
的字符串,在最坏的情况下(如果所有字符都不同),您将有
2^N-1
不同的非空子集对于由
L
字符组成的每个子集,您将有
L!
排列。我不知道如何做到这一点,您能详细说明一下吗?我想这里有一些问题。比如字符串“acbc”您的结果:1A2C3ACB4ACBC5ACC6ACCB7B8BA9BAC10BACC12BCC114BCC15BCA16CAB17CAB19CA BC20CAC22CB23CBA24CBAC25CBC26CBCA27CC28CCA29CCAB30CCB310CCB31CCB7BA8BC13BC14CAB15BAC17CAB17CAB18CAB17CAB19CAB15BAC16CAB17CAB17CAB18CAB18CB18CBA18CBA18CAB19CAB29CAC21CA22AB23ACB24BAC26CAB28BC29cbc30ccb31abcc32acbc33accb34bacc35bcac36bcca37cabc38cacb39cbac40cbca41ccab42ccba@GG:啊,一开始我没注意到:下一个置换需要对初始状态进行排序,如果你想遍历所有置换。如果必要,请使用std::sort。我不知道怎么做,你能详细说明一下吗?我想这里有一些问题。lets表示字符串“acbc”您的结果:1A2C3ACB4ACBC5ACC6ACCB7B8BA9BAC10BACC12BCC114BCC15BCA16CAB17CAB19CA BC20CAC22CB23CBA24CBAC25CBC26CBCA27CC28CCA29CCAB30CCB310CCB31CCB7BA8BC13BC14CAB15BAC17CAB17CAB18CAB17CAB19CAB15BAC16CAB17CAB17CAB18CAB18CB18CBA18CBA18CAB19CAB29CAC21CA22AB23ACB24BAC26CAB28BC29cbc30ccb31abcc32acbc33accb34bacc35bcac36bcca37cabc38cacb39cbac40cbca41ccab42ccba@GG:啊,我一开始没注意到:下一个置换要求对初始状态进行排序,如果你想进行所有置换。如果需要,请使用std::sort。这样我可以使输出大小变长,因为我使用它来打印序列号。对于int,我可以生成e组合高达n=32@GG仅打印10^9个不同的字符串需要将近一个小时的时间(大约10GB的磁盘空间)。这是您想要的吗?@nikita我看不到其他方法?或者我应该设置一个限制,请不要给我大于9的数字。@GG不打印就无法打印10^9个字符串。(若您更改了要求,例如,若您决定只想知道这些字符串的数量,那个将是一个不同的故事。)因此,我的建议是继续使用您当前的程序:您不会得到更快的解决方案。感谢nikita,我最好遵守要求。这样我可以使输出大小变长,因为我使用它打印序列号。对于int,我可以生成高达n=32@GG仅打印10^9个不同的字符串就需要将近一个小时的时间(和大约10GB的磁盘空间)。这是你想要的吗?@nikita我看不到任何其他的方式?或者我想
#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;
}
#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;
}