如将s="ABCD"实现排列组合,有4!种排列方式。
思路:s的排列可分为:
'A'打头的6个排列;
'B'打头的6个排列;
'C'打头的6个排列;
'C’打头的6个排列;
而每个以A打头的排列中,在A的后面跟着是BCD的不同排列组合。这就给出了一个递归的解决方法。
/*用递归进行全排列*/
#include <iostream>
#include <string>
using namespace std;
void rec_permute(string s,unsigned k)//由于rec_permute的参数是值传递,所以在递归调用过程中不会改变s的值。
{
if(k==s.length()-1)
cout<<s<<endl;
else
for(unsigned i=k;i<s.length ();i++)
{
swap(s[i],s[k]);
rec_permute(s,k+1);
}
}
void permute(const string& s)//包装函数,该函数包含一个常量引用参数s,并把s传递给递归函数。那么permute函数执行后原始的字符串S将不会改变
{
rec_permute(s,0);
}
int main()
{
string s="ABCD";
permute(s);
return 0;
}
注意:s的值在递归调用过程中是不会改变的,因为s是rec_permute的一个传值参数。但是在swap中,会改变s的值。
在最外面的for循环中:
第一次循环:s的状态是ABCD,swap之后还是ABCD,之后调用rec_permute(s,k+1),但调用rec_permute(s,k+1)并不会改变s的值,所以第一次循环结束之后,s为ABCD。
第二次循环:s的状态是ABCD,swap之后是BACD,之后调用rec_permute(s,k+1),但调用rec_permute(s,k+1)并不会改变s的值,所以第一次循环结束之后,s为BACD。
第三次循环:s的状态是BACD,swap之后是CABD。
第四次循环:s的状态是CABD,swap之后是DABC。
整个递归调用的worstTime(n)是O(n!),worstSpace(n)为O(n^2)。