全排列的递归解法
2016-02-03 18:00
337 查看
算法思想:
假定有一个数组,int[] = {1,2,3,4,5};
1.先看数组的最后两个元素:{4,5},它的全排列即是45,54.
2.再看数组的最后三个元素:{3,4,5},它的全排列即是345,354,435,453,534,543.
3.N个元素S = {r1,r2,r3,...,r(n-1),rn}的全排列即是
r1P(S-r1),r2P(S-r2),r3P(S-r3),...,rnP(S-rn);此处P(S-r1)为S数组过滤掉r1后的全排列.
4.依次将待排列的数组的后N-1个元素与第一个元素交换,则每次递归处理的都是后N-1个元素的全排列.当数组元素仅有一个时为此递归算法的出口.
假定有一个数组,int[] = {1,2,3,4,5};
1.先看数组的最后两个元素:{4,5},它的全排列即是45,54.
2.再看数组的最后三个元素:{3,4,5},它的全排列即是345,354,435,453,534,543.
3.N个元素S = {r1,r2,r3,...,r(n-1),rn}的全排列即是
r1P(S-r1),r2P(S-r2),r3P(S-r3),...,rnP(S-rn);此处P(S-r1)为S数组过滤掉r1后的全排列.
4.依次将待排列的数组的后N-1个元素与第一个元素交换,则每次递归处理的都是后N-1个元素的全排列.当数组元素仅有一个时为此递归算法的出口.
/* *算法思想:简单地说:就是第一个数分别以后面的数进行交换 *E.g:E = (a , b , c),则 prem(E)= a.perm(b,c)+ b.perm(a,c)+ c.perm(a,b) *然后a.perm(b,c)= ab.perm(c)+ ac.perm(b)= abc + acb.依次递归进行。 *去掉重复符号的全排列:在交换之前可以先判断两个符号是否相同,不相同才交换, *这个时候需要一个判断符号是否相同的函数。 */ #include <iostream> #include <algorithm> using namespace std; int cnt = 1; //记录排列的个数 bool isSwap(int p[],int nBegin, int nEnd) { for(int i = nBegin; i < nEnd; i++) { if(p[i] == p[nEnd]) return false; } return true; } //start 表示当前的数,n表示数组中数的个数 void permutation(int p[],int cur,int n) { if(cur == n-1) { cout<<"第"<<cnt++<<"个全排列: "; for(int i = 0; i < n; i++) cout<<p[i]; cout<<endl; } else { for(int i = cur; i <= n-1; i ++) //第i个数分别与它后面的数字交换就能得到新的排列 { if(isSwap(p,cur,i)) //判断是否相等,中间是相等的元素则不需交换 { swap(p[cur],p[i]); permutation(p,cur+1,n); swap(p[cur],p[i]); } } } } int main() { int p[] = {1,2,2,4}; permutation(p,0,4); return 0; }
相关文章推荐
- Lotus Domino中使用Xpage技术打造通讯录
- CSS基础知识——选择器
- get_called_class--后期静态绑定("Late Static Binding")类的名称
- Android Jni Android.mk常用语句
- 配置MySQL GTID 主从复制
- JVM源码分析之Attach机制实现完全解读
- hibernate之insert和update控制实战
- iOS控件之UIResponder
- 收藏2
- [CodeForces #80 Div 1 D] 分块+树状数组/线段树
- Java项目开发环境构建工具 Gradle 使用笔记(简单、基本)
- 使用LS2J技术在LotusScript中使用Java
- class_exists — 检查类是否已定义
- JVM源码分析之堆外内存完全解读
- 进制转换 2
- 进制转换 2
- 规范
- 收藏1
- 【UOJ#171】【WC2016】挑战NPC【带花树开花】
- Android FFmpeg