问题:给定字符串S,生成该字符串的全排列。
方法1:依次从字符串中取出一个字符作为最终排列的第一个字符,对剩余字符组成的字符串生成全排列,最终结果为取出的字符和剩余子串全排列的组合。
#include <iostream> #include <string> usingnamespacestd; voidpermute1(string prefix, string str) { if(str.length() == 0) cout << prefix << endl; else { for(inti = 0; i < str.length(); i++) permute1(prefix+str[i], str.substr(0,i)+str.substr(i+1,str.length())); } } voidpermute1(string s) { permute1(“”,s); } intmain() { //method1, unable to remove duplicate permutations. cout << “method1″<< endl; permute1(“ABA”); } |
优点:该方法易于理解,但无法移除重复的排列,如:s=”ABA”,会生成两个“AAB”。
方法2:利用交换的思想,具体见实例,但该方法不如方法1容易理解。
一个字符串的各个字符位置为: 0, 1, 2, 3, …, K, K+1, …, m
1) 一般的,对于从K开始的字符串的可以排列为:K(K+1,K+2, K+3,…), K+1(K,K+2, K+3,…), K+2(K,K+1, K+3,…), …
也就是说 swap(K, i(K<= i <= m)) 即可;
2) 递归过程, K向后步进1: perm(K+1);
3) 递归的边界条件: K > m.
#include <iostream> #include <string> #include <cstdio> usingnamespacestd; voidswap(char* x, char* y) { chartmp; tmp = *x; *x = *y; *y = tmp; } /* Function to print permutations of string This function takes three parameters: 1. String 2. Starting index of the string 3. Ending index of the string. */ voidpermute(char*a, inti, intn) { intj; if(i == n) printf(“%s\n”, a); else { for(j = i; j <= n; j++) { if(a[i] == a[j] && j != i) //为避免生成重复排列,当不同位置的字符相同时不再交换 continue; swap((a+i), (a+j)); permute(a, i+1, n); swap((a+i), (a+j)); //backtrack } } } intmain() { //method2 cout << “method2″<< endl; chara[] = “ABA”; permute(a,0,2); return0; } |
两种方法的生成结果:
method1 ABA AAB BAA BAA AAB ABA method2 ABA AAB BAA 请按任意键继续. . . |