标签:c algorithm combinations permutation
我需要通过选择一些元素来生成字符串的所有排列.就像我的字符串是“ abc”一样,输出将是{a,b,c,ab,ba,ac,ca,bc,cb,abc,acb,bac,bca,cab,cba}.
我想到了一种基本算法,在该算法中,我生成{a,b,c,ab,ac,bc,abc}的所有“ 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;
}
我需要使用哈希来避免相同的组合,因此请让我知道如何使该算法更好.
谢谢,
GG
解决方法:
我不认为您可以编写比现在更快的程序.主要问题是输出大小:它的阶数为n!* 2 ^ n(子集数*一个子集的平均排列数),该值已经大于. 10个9个字符的字符串为10 ^ 9.
由于STL的next_permutation为这样的小字符串增加了非常有限的复杂度,因此程序的时间复杂度已经接近O(输出大小).
但是您可以使程序更简单.特别地,for(k = 1; k <= n; k)循环似乎是不必要的:您已经在变量c内部计算了子集的大小.因此,只用int k = c代替if(c == k). (您还需要考虑空子集的情况:i == 0)
编辑
实际上,对于n == 10,只有9864100个输出(不是〜10 ^ 9).尽管如此,我的观点仍然是相同的:您的程序已经为每个输出仅浪费了“ O(next_permutation)”时间,这非常少.
标签:c,algorithm,combinations,permutation 来源: https://codeday.me/bug/20191012/1902312.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。