递归求解思路:
1) 每个元素依次放到首位,然后对其余元素递归
2) 当当前元素到达末尾的时候,输出该序列
关键是:
每个元素交换完,之后要交换过来。每个元素依次放到首位,
for(int i=currentIndex;i<=n;++i){ swap 从i+1递归 swap }
#include<stdio.h> #include<stdlib.h> #define SWAP(x,y,t)((t)=(x),(x)=(y),(y)=(t)) int score=0; void perm(int *list,int i,int n) { int j,temp; if(i==n) { for(j=0;j<=n;j++) { printf("%d ",list[j]); } printf("\n"); score++; } else { for(j=i;j<=n;j++) { SWAP(list[i],list[j],temp); perm(list,i+1,n); SWAP(list[i],list[j],temp); } } } int main() { int list[]={1,2,3}; perm(list,0,2); printf("Thetotal number is %d\n",score); system("pause"); }
String 版本
#include <iostream> using namespace std; void Permutation(string pStr, int k, int n) { if(k==n) cout<<pStr<<endl; for(int i=k;i<n;++i) { swap(pStr.at(i),pStr.at(k)); Permutation(pStr, k+1,n); swap(pStr.at(i),pStr.at(k)); } } int main() { strings="abcdef"; Permutation(s,0,s.length()); }
二,扩展
如果不是求字符的所有排列,而是求字符的所有组合,应该怎么办呢?(P72)
思路:这里不采用交换方式,而是采用删减的方式。采用不同的剔除顺序,并用prex保留删减值,这样将得到所有符合条件的序列
#include <iostream> using namespacestd; voidselect(string str, string prex) { string temp=str; cout<<prex<<endl; for(int i=0;i<str.length();++i) { select(str.erase(i,1),prex+str.at(i)); str=temp; } } int main() { string s="abcd"; select(s,""); }
扩展二:
当输入的字符串中含有相同的字符串时,相同的字符交换位置是不同的排列,但是同一个组合。
举个例子,如果输入aaa,那么它的排列是6个aaa,但对应的组合只有一个。