Je dois générer toute la permutation d'une chaîne en sélectionnant certains des éléments. Comme si ma chaîne est "abc", la sortie serait {a, b, c, ab, ba, ac, ca, bc, cb, abc, acb, bac, bca, cab, cba}.Algorithme pour générer toutes les permutations en sélectionnant certains ou tous les charaters
Je pensais un algorithme de base dans lequel je génère toutes les combinaisons possibles de "abc" qui sont {a, b, c, ab, ac, bc, abc}, puis les permuter tous.
Y a-t-il donc un algorithme de permutation efficace par lequel je peux générer toutes les permutations possibles avec des tailles variables.
Le code que j'ai écrit pour cela est:
#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;
}
je dois utiliser un hachage pour éviter même combinaison, alors s'il vous plaît laissez-moi savoir comment puis-je faire mieux cet algorithme.
Merci, GG
Je n'ai pas lu votre code, mais votre description verbale semble correcte: utilisez [http://en.wikipedia.org/wiki/Power_set] avec permutation. Pour énumérer un * ensemble d'alimentation *, pensez à incrémenter un nombre binaire, où chaque "chiffre" correspond au nombre de fois qu'un élément d'entrée a été sélectionné pour apparaître dans la sortie. Pour les éléments répétés dans l'ensemble d'entrée, certains "chiffres" du nombre "binaire" deviendront ternaires, ou le nombre de répétitions de cet élément. – rwong
Notez que pour une chaîne de longueur 'N' vous aurez' 2^N-1' sous-ensembles distincts non vides dans le pire des cas (si tous les caractères sont différents) et pour chaque sous-ensemble constitué de caractères 'L', vous Je vais avoir des permutations 'L! –