递归求解思路:
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,但对应的组合只有一个。