字符串的全排列
2016-05-01 16:57
357 查看
字符串的全排列问题:
给定字符串S[0...N-1],设计算法,枚举字符串的全排列。
1、无重复字符串全排列非递归算法
程序实现:
运行结果:
说明:在每次递归前需要保证字符串的顺序不变,因此有每次的替换过程。
2、有重复字符串队规算法
程序实现:
运行结果:
说明:本算法时间复杂度能达到O((n+1)!),不可取。
改进:利用空间换时间,采用下列的程序实现:
运行结果:
3、使用求下一个排列的思想,构造非递归算法。
过程:从当前排列生成字典序刚好比它大的下一个排列。
程序实现:
运行结果:
说明:非递归算法天然解决重复字符问题。
另附上全部实现程序,仅供参考:
转载请注明出处:
C++博客园:godfrey_88
http://www.cnblogs.com/gaobaoru-articles/
给定字符串S[0...N-1],设计算法,枚举字符串的全排列。
1、无重复字符串全排列非递归算法
程序实现:
//无重复字符串的全排列递归算法 void Permutaion(int* a,int size,int index){ if(index == size-1){ Print(a,size); return; } for(int i=index;i<size;i++){ swap(a[i],a[index]); Permutaion(a,size,index+1); swap(a[i],a[index]); } }
运行结果:
说明:在每次递归前需要保证字符串的顺序不变,因此有每次的替换过程。
2、有重复字符串队规算法
程序实现:
//判断从a[to]是否与(index,to)重复 bool IsDuplicate(int* a,int index,int to){ while(index<to){ if(a[index]==a[to]){ return true; } index++; } return false; } //有重复字符串的全排列递归算法,Time Cost O((n+1)!) void Permutaion1(int* a,int size,int index){ if(index == size-1){ Print(a,size); return; } for(int i=index;i<size;i++){ if(!IsDuplicate(a,index,i)){ swap(a[i],a[index]); Permutaion1(a,size,index+1); swap(a[i],a[index]); } } }
运行结果:
说明:本算法时间复杂度能达到O((n+1)!),不可取。
改进:利用空间换时间,采用下列的程序实现:
//有重复字符串的全排列递归算法,空间换时间 void Permutaion2(int* a,int size,int index){ if(index == size-1){ Print(a,size); return; } int dup[256] = {0}; for(int i=index;i<size;i++){ if(dup[a[i]]==1) continue; dup[a[i]] = 1; swap(a[i],a[index]); Permutaion2(a,size,index+1); swap(a[i],a[index]); } }
运行结果:
3、使用求下一个排列的思想,构造非递归算法。
过程:从当前排列生成字典序刚好比它大的下一个排列。
程序实现:
//字符串全排列非递归算法,求下一个排列的思想 void Reverse(int* from,int* to){ int t; while(from<to){ t = *from; *from = *to; *to = t; from++; to --; } } bool GetNextPermutation(int* a,int size){ //后找,从后向前找最后一个升序的位置 int i = size-2; while((i>=0)&&(a[i]>=a[i+1])) i--; if(i<0) return false; //查找,从后面的元素中寻找比a[i]大的最小值a[j] int j=size-1; while(a[j]<=a[i]) j--; //交换 swap(a[i],a[j]); //翻转 a[i+1...N-1] Reverse(a+i+1,a+size-1); return true; }
运行结果:
说明:非递归算法天然解决重复字符问题。
另附上全部实现程序,仅供参考:
/*************************************** FileName StringPermutation.cpp Author : godfrey CreatedTime : 2016/5/1 ****************************************/ #include <iostream> #include <cstring> #include <vector> #include <algorithm> #include <stdio.h> #include <stdlib.h> using namespace std; void Print(const int* a,int size){ for(int i=0;i<size;i++){ cout<<a[i]<<' '; } cout<<endl; } //无重复字符串的全排列递归算法 void Permutaion(int* a,int size,int index){ if(index == size-1){ Print(a,size); return; } for(int i=index;i<size;i++){ swap(a[i],a[index]); Permutaion(a,size,index+1); swap(a[i],a[index]); } } //判断从a[to]是否与(index,to)重复 bool IsDuplicate(int* a,int index,int to){ while(index<to){ if(a[index]==a[to]){ return true; } index++; } return false; } //有重复字符串的全排列递归算法,Time Cost O((n+1)!) void Permutaion1(int* a,int size,int index){ if(index == size-1){ Print(a,size); return; } for(int i=index;i<size;i++){ if(!IsDuplicate(a,index,i)){ swap(a[i],a[index]); Permutaion1(a,size,index+1); swap(a[i],a[index]); } } } //有重复字符串的全排列递归算法,空间换时间 void Permutaion2(int* a,int size,int index){ if(index == size-1){ Print(a,size); return; } int dup[256] = {0}; for(int i=index;i<size;i++){ if(dup[a[i]]==1) continue; dup[a[i]] = 1; swap(a[i],a[index]); Permutaion2(a,size,index+1); swap(a[i],a[index]); } } //字符串全排列非递归算法,求下一个排列的思想 void Reverse(int* from,int* to){ int t; while(from<to){ t = *from; *from = *to; *to = t; from++; to --; } } bool GetNextPermutation(int* a,int size){ //后找,从后向前找最后一个升序的位置 int i = size-2; while((i>=0)&&(a[i]>=a[i+1])) i--; if(i<0) return false; //查找,从后面的元素中寻找比a[i]大的最小值a[j] int j=size-1; while(a[j]<=a[i]) j--; //交换 swap(a[i],a[j]); //翻转 a[i+1...N-1] Reverse(a+i+1,a+size-1); return true; } int main() { int a[] = {1,2,3,4}; cout<<"-----无重复字符串全排列递归算法-------"<<endl; Permutaion(a,sizeof(a)/sizeof(int),0); int a1[] = {1,2,2,3}; cout<<"-----有重复字符串全排列递归算法-------"<<endl; Permutaion1(a1,sizeof(a1)/sizeof(int),0); cout<<"-----有重复字符串全排列递归算法(空间换时间)-------"<<endl; Permutaion2(a1,sizeof(a1)/sizeof(int),0); cout<<"-----字符串全排列非递归算法------------"<<endl; int size = sizeof(a)/sizeof(int); Print(a,size); while(GetNextPermutation(a,size)) Print(a,size); return 0; }
转载请注明出处:
C++博客园:godfrey_88
http://www.cnblogs.com/gaobaoru-articles/
相关文章推荐
- c++11 正则表达式基本使用
- 每天一个Linux命令(2)cd命令
- iOS - 加速计程序的开发
- 第1课:SparkStreaming 三板斧之一:解密SparkStreaming另类实验及SparkStreaming本质解析
- Android 学习资料收集
- html原生select改造箭头及文字左右居中的一种办法
- [Unity3D]简单使用Protobuf-net(二)
- jQuery常用插件
- POJ 3714(Raid-平面最近点对)
- 0501-学习进度条
- TOMCAT中 workers.properties配置说明
- Android活动的生存期
- Unity3D中角色的动画脚本的编写
- LR 打不开IE的解决方法
- SurfaceView和View的区别
- 剑指offer(64):二叉搜索树的第k大的节点
- 浅谈提高团队成员的工作积极性
- MySQL 单表查询
- iOS视图控制器编程指南 --- 定义你的子类
- Apache+Tomcat服务器集群配置详细步骤