STL有全排列函数next_permutation:传送门

不过还是自己写写比较好啊~

自己写全排列:

#include <iostream>
#include <algorithm>
using namespace std;const int MAXN = 105;
int a[MAXN];
int n,cnt;
inline void mySwap(int i,int j)
{int temp;temp = a[i];a[i] = a[j];a[j] = temp;
}
inline void print(int *a)
{for(int i = 0; i < n; i++){cout<<a[i]<<" ";}cout<<"\n";
}
/*
全排列递归写法(非字典序)
基本思想:
每次固定该序列的某一个数(固定到s位置),
然后递归调用s之后构成的子序列全排列,
直到需要全排列的子序列只有一个数就先打印出整个序列
然后递归返回
*///去重
bool check(int cur)
{for(int i = cur+1; i < n; i++)//当前交换的与它后面的数有重复,当前位置先不交换{if(a[cur] == a[i])return false;}return true;
}
/*
解释“当前交换的与它后面的数有重复,当前位置先不交换”,而为什么不使用当前位置,而让后面重复的不使用呢?
这是为了判断效率,降低判断难度啊,要判断 当前序列中这个打算用来交换的数 在当前这个序列 这个数之前 有没有被使用,
是需要知道 这个子序列的 起始位置的,
因为是递归,而每个子序列的起始位置都不同,明显更不好处理,所以。。。
*/
void permutation(int *a,int s)
{if(s == n){cnt++;print(a);return;}for(int i = s; i < n; i++){if(check(i)){mySwap(s,i);permutation(a,s+1);mySwap(s,i);}}
}/*
全排列非递归算法,
并且字典序,
会去重
理解:
因为要字典序,首先就要让它第一个序列有序(升序),
(对于全是数字来说,全排列字典序就是要让能组成的数字从小到大排列)
要得到其他序列,
用例子来说明:
序列: 1 2 3 4
1 2 3 4 就是它的全排列的第一个序列
之后肯定要找到最后一对a[i]<a[i+1],pos = i,
再找pos之后最后一个a[i] > a[pos],k = i
交换pos ,k这两个位置上的值
a[pos] = 3
a[k] =  4
得到:
1 2 4 3
//这里好像交换后就不需要再做任何操作了,后面也是吗?
继续做下去:
a[pos] = 2
a[k] = 3
交换a[pos] 与a[k]
得到:
1 3 4 2
这里明显不是我们预先想得到的,我们要得到的是:1 3 2 4
我们发现交换后把pos位置之后的序列反转就是我们想要的
这到是否有通用性,或者是否是正确的做法呢?
仔细想一想,之前的交换总会使此时pos位置后的子序列,
如果把它看成一个数字,那么它会逐渐变为最大,
但是对于当前pos,后面的序列看成一个数字应该要是最小的,
所以此时pos位置后序列作反转一定是具有通用性,正确性!!
so:交换之后,一定要反转pos位置之后的序列
前面有看起来不用反转,是因为pos位置后的子序列只有一个数,当然看不出要反转~
概括总步骤:
1.如果原始序列无序,必须先排序,有序的序列为全排列的第一个序列
2.找最后一对a[i] < a[i+1] ,pos = i
3.pos后找最后一个a[i] > a[pos], k = i
4.交换a[pos],a[k]的值
5.反转pos之后的序列
6.打印当前序列(这个序列为全排列得到的下一个序列)
repeat上述步骤,直到找不到pos
*/
void permutationTwo(int *a)
{sort(a,a+n);//第一个要打印出来cnt++;print(a);while(1){int pos = -1;/*从前往后找最后一个:a[i]<a[i+1],pos = i,现在从后往前找以提高效率,即转化为第一个:a[i] > a[i-1],pos = i - 1;*/for(int i = n-1; i > 0; i--)//i > 0 防止数组越界{if(a[i] > a[i-1]){pos = i - 1;break;}}if(pos == -1) break;int k = -1;/*找pos之后最后一个a[i] > a[pos],k = i,从后向前找即第一个a[i] > a[pos],k = i*/for(int i = n-1; i > pos; i--){if(a[i] > a[pos]){k = i;break;}}//交换pos,k两个位置元素的值mySwap(pos,k);//反转pos之后元素for(int i = pos+1,j = n-1; i <= j; i++,j--){mySwap(i,j);}cnt++;//打印permutationprint(a);}
}
int main()
{cin>>n;for(int i = 0; i < n; i++){cin>>a[i];}cout<<"permutation:"<<endl;permutation(a,0);cout<<"permutation count = "<<cnt<<endl;cnt = 0;cout<<"permutationTwo:"<<endl;permutationTwo(a);cout<<"permutationTwo count = "<<cnt<<endl;return 0;
}

测试结果:

时间复杂度:
递归和非递归都近似O(n!)
但是非递归相对要慢一些,因为它在其他方面,
比如反转,查找等方面增加了时间消耗。

Algorithm of permutation(全排列算法)相关推荐

  1. 【转】全排列算法非递归实现和递归实现

    来源:http://blog.csdn.net/e3399/article/details/7543861 (一)递归的全排列算法 (A.B.C.D)的全排列为 1.A后面跟(B.C.D)的全排列 2 ...

  2. C++ vector 容器的全排列算法 next_permutation

    问题源于我要对4个数进行排列,自己用了笨拙的穷举算法一个4重循环也得到结果,其中对有相同字母的做排序加删除相邻相等元素的处理.可是如果对100个数进行排列难道用100重循环,后来发现C++11有现成的 ...

  3. [通用技术]在不同语言中用协程实现全排列算法(C++/Lua/Python/C#)

    我这里实现全排列的基本算法如下(C++): 1 #include <algorithm> 2 #include <iostream> 3 #include <vector ...

  4. 全排列及相关扩展算法(一)——基础的回溯递归实现全排列算法

    1.全排列的定义和公式: 从n个数中选取m(m<=n)个数按照一定的顺序进行排成一个列,叫作从n个元素中取m个元素的一个排列.由排列的定义,显然不同的顺序是一个不同的排列.从n个元素中取m个元素 ...

  5. 全排列的java算法_全排列算法原理和实现

    评论 # re: 全排列算法原理和实现  回复  更多评论 #include #include #define CHESSNUM 9 using namespace std; /*********** ...

  6. 字符串全排列算法_C#版_剑指OFFER

    字符串全排列算法_C#版_剑指OFFER 题目描述 ​题目描述 输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组. 例如输入字符串ABC,则输出由字符A, ...

  7. 蓝桥杯——Java中的全排列算法

    蓝桥杯--Java中的全排列 全排列的概念 排列 从n个数中选取m(m<=n)个数按照一定的顺序进行排成一个列,叫作从n个元素中取m个元素的一个排列.不同的顺序是一个不同的排列.从n个元素中取m ...

  8. 全排列算法(无重复数字全排列/有重复数字全排列)/ 组合算法/ 求子集算法

    写在前面 全排列 1 无重复数字全排列 1.1 紫书版本 1.2 回溯法 2 有重复数字全排列 复盘易错点(可跳过) 写在前面 很久很久以前就想写的一篇博客,因为懒一直没开工,但是学习全排列算法算是我 ...

  9. 字典序全排列算法(非递归全排列算法)

    非递归全排列算法: 我们先看一个例子. 示例: 1 2 3的全排列如下: 1 2 3 , 1 3 2 , 2 1 3 , 2 3 1 , 3 1 2 , 3 2 1 我们这里是通过字典序法找出来的. ...

最新文章

  1. ASP.NET MVC 2示例Tailspin Travel
  2. ES6中新增字符串方法,字符串模板
  3. 电脑不能打字_意外收到一台ThinkPad T400笔记本电脑,简单升级后,办公没问题...
  4. UEFI下面安装win7+Xubuntu18.10双系统
  5. kafka maven没有下载_构建工具的进化:ant, maven, gradle
  6. select下拉框带模糊查询_如何实现参数级联查询
  7. 请还未提交实名的博客专家在8月4日前尽快提交您的实名信息
  8. 总结几个与模块相关的命令
  9. PHP mysql_connect() 函数
  10. 《产品结构设计》——黎恢来,笔记
  11. ubuntu格式化磁盘并挂载
  12. KY-RTI分布仿真技术:第二章 系统安装
  13. 如何快速入门成为一名数据分析师
  14. mysql中获取时间的年月日_详解mysql 获取当前日期及格式化
  15. WPF如何用TreeView制作好友列表、播放列表
  16. 11月NEO技术社区开发进展汇总
  17. 基于51单片机数字电压表的设计 仿真、程序、原理图(转发)
  18. 数模matlab入门教程-001-xlsread用法
  19. Python 图形界面开发哪个库好
  20. Protocol Labs协议实验室介绍

热门文章

  1. kafka+zookeeper安装配置
  2. 自然语言处理之词向量模型(三)
  3. 一文学会设置 Jupyter 主题与目录
  4. 最受 IT 公司欢迎的 30 款开源软件
  5. GitHub 开源神器:堪称作业终结者!
  6. python基础list_python基础之List详解
  7. 计算机网络技术发源于什么,计算机网络基础试题和答案
  8. java 子类中this,请问子类中的构造方法中 this(name,beijing,school);是啥意思
  9. 并查集【CF731C】Socks
  10. DOS中判断进程是否存在的方法