也论全排列的递归实现
来源:互联网 发布:nvslp监控软件下载 编辑:程序博客网 时间:2024/05/29 12:44
今天在专栏里看到这样一个帖子
http://blog.csdn.net/morewindows/article/details/7370155
举了一个题目是这样的
用C++写一个函数, 如 Foo(const char *str), 打印出 str 的全排列,
如 abc 的全排列: abc, acb, bca, dac, cab, cba
但是对于该帖子关于全排列递归实现的思路理解起来总是觉得很别扭,怪怪的。所以就根据自己的理解,
自己写了个函数。
一、递归函数
我理解的递归函数就是 f(n)=Pf(n-1) //P表示某种方法的转换
f(1)=X //X为解决方法的确定值
满足这样的条件,那么就可以通过f(1)的值,解决f(n)的问题了。
二、关于字符串全排列的理解
字符串abc的全排列结果为:
为 abc
acb
bac
bca
cba
cab
可以发现全排列的规律就是 abc 把: a拿出来然后字符串bc进行全排列,然后按顺序把b拿出来ac进行全排列,最后再把c拿出来字符串ab进行全排列。
按照开始对递归函数的理解,写出的表达式为
RN表示一个字符 f(R1R2R3...RN) 为字符串 R1R2R3....RN的全排列
结果: f(R1R2R3...RN)=R1f(R2R3...RN)
f(RN)=RN //只有一个字符的时候RN自己就是自己的全排列
三、算法
根绝上面的理解,那么算法就很容易写出来了
#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,所以就不进行操作了,也就解决的字符串
中有重复字符的问题。
- 也论全排列的递归实现
- 排列的递归实现
- 排列的非递归实现
- 全排列的递归实现
- 全排列的递归实现
- 去重全排列的递归实现
- 全排列的递归实现
- 全排列的递归实现
- 新解全排列的递归实现
- 全排列的递归实现
- 全排列的递归实现
- 全排列的递归实现
- 字符串的递归排列实现
- 全排列的递归实现
- 全排列的递归实现
- 全排列的递归实现
- 全排列的递归实现与非递归实现
- 全排列的非递归实现及递归实现
- window.onload的加载时间
- RAC上 read by other session 解决一例
- UICatalog 随手记
- 学习OpenCV——SVM
- 字符串中字符'\0'是二进制值为零
- 也论全排列的递归实现
- Windows Phone中的路由事件-以ListBox控件为例
- poj Labeling Balls 3687 拓扑排序!!!!
- Dataguard的switchover 和failover 并将老主库flashback 成standby库
- 9省启动IPv6试点
- Silverlight 基础收集
- 配置apache反向代理,解决js跨域问题
- IOS多线程读写Sqlite问题解决
- RAC搭建standby