全排列递归算法
一、题目:用C++写一个函数, 如 Foo(const char *str), 打印出 str 的全排列(注意:输入的字符串可能有重复字符),
如 abc 的全排列: abc, acb, bca, dac, cab, cba
二、关于字符串全排列的理解
字符串abc的全排列结果为:
abc
acb
bac
bca
cba
cab
字符串abb的全排列为:
abb
bab
bba
可以发现全排列的规律就是 abc 把: a拿出来然后字符串bc进行全排列,然后按顺序把b拿出来ac进行全排列,最后再把c拿出来字符串ab进行全排列。
三、算法
根据上面的理解,那么算法就很容易写出来了
#include "stdafx.h"
#include "stdio.h"
#include "iostream"
#include "string"
void swap(char &a ,char &b) //字符移位函数
{
char m ;
m = a;
a = b;
b = m;
}
bool isSwap(char * str,int i,int k)//出来字符串中有重复字符出现的情况
{
for(int p=k;p<i;p++)
{
if(str[p]==str[i])
return false;
}
return true;
}
void allrange(char * str,int k,int m)//全排列的递归函数
{
if(k==(m-1))
{
printf("%s\n",str);
}else
{
for(int i=k;i<m;i++)
{
if(isSwap(str,i,k))
{
swap(str[i],str[k]);
allrange(str,k+1,m);
swap(str[i],str[k]);
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char str[100];
while(1)
{
printf("%s","请输入要全排列的字符串:\n");
std::cin>>str;
printf("%s","全排列的结果为:\n");
allrange(str,0,strlen(str));
}
return 0;
}
四、运行效果
五、总结
在上面的算法中还考虑到了有重复字符出现的情况,
如 abb这种字符串 递归的流程是 先把a拿出来然后字符串bb进行全排列,再把b拿出来,ab进行全排列,
最后一步将第三个字符串b拿出来ab进行全排列,这样就重复了。解决的方法就是每取一个字符的时候,都让
这个字符前面的字符与其比较,如果想当那就不用进行操作了。
bool isSwap(char * str,int i,int k)//出来字符串中有重复字符出现的情况
此函数就是解决这个问题的。添加的这个函数,那么比如上面abb这个问题的时候,当按照算法取第三个字符
也就是b的时候,会跟前面两个字符一次比较,由于第二个字符也是b,所以就不进行操作了,也就解决的字符串
中有重复字符的问题。