【STL】全排列生成算法:next_permutation
C++/STL中定义的next_permutation和prev_permutation函数是非常灵活且高效的一种方法,它被广泛的应用于为指定序列生成不同的排列。
next_permutation函数将按字母表顺序生成给定序列的下一个较大的排列,直到整个序列为降序为止。
prev_permutation函数与之相反,是生成给定序列的上一个较小的排列。
所谓“下一个”和“上一个”,举一个简单的例子:
对序列 {a, b, c},每一个元素都比后面的小,按照字典序列,固定a之后,a比bc都小,c比b大,它的下一个序列即为{a, c, b},而{a, c, b}的上一个序列即为{a, b, c},同理可以推出所有的六个序列为:{a, b, c}、{a, c, b}、{b, a, c}、{b, c, a}、{c, a, b}、{c, b, a},其中{a, b, c}没有上一个元素,{c, b, a}没有下一个元素。
二者原理相同,仅遍例顺序相反,这里仅以next_permutation为例介绍算法。
(1) int 类型的next_permutation
int main()
{
int a[];
a[]=;a[]=;a[]=;
do
{
cout<<a[]<<" "<<a[]<<" "<<a[]<<endl;
}while (next_permutation(a,a+)); //参数3指的是要进行排列的长度 //如果存在a之后的排列,就返回true。如果a是最后一个排列没有后继,返回false,每执行一次,a就变成它的后继
}
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
如果改成
while(next_permutation(a,a+));
则输出:
1 2 3
2 1 3
只对前两个元素进行字典排序
显然,如果改成
while(next_permutation(a,a+));
则只输出:1 2 3
若排列本来就是最大的了没有后继,则next_permutation执行后,会对排列进行字典升序排序,相当于循环
int list[]={,,};
next_permutation(list,list+);
cout<<list[]<<" "<<list[]<<" "<<list[]<<endl;
输出: 1 2 3
(2) char 类型的next_permutation
int main()
{
char ch[];
cin >> ch; sort(ch, ch + strlen(ch) );
//该语句对输入的数组进行字典升序排序。如输入9874563102
cout<<ch;//将输出0123456789,这样就能输出全排列了 char *first = ch;
char *last = ch + strlen(ch); do {
cout<< ch << endl;
}while(next_permutation(first, last));
return ;
} //这样就不必事先知道ch的大小了,是把整个ch字符串全都进行排序
//若采用 while(next_permutation(ch,ch+5)); 如果只输入1562,就会产生错误,因为ch中第五个元素指向未知
//若要整个字符串进行排序,参数5指的是数组的长度,不含结束符
(3) string 类型的next_permutation
int main()
{
string line;
while(cin>>line&&line!="#")
{
if(next_permutation(line.begin(),line.end())) //从当前输入位置开始
cout<<line<<endl;
else cout<<"Nosuccesor\n";
}
}
int main()
{
string line;
while(cin>>line&&line!="#")
{
sort(line.begin(),line.end());//全排列
cout<<line<<endl;
while(next_permutation(line.begin(),line.end()))
cout<<line<<endl;
}
}
next_permutation 自定义比较函数
#include<iostream> //poj 1256 Anagram
#include<cstring>
#include<algorithm>
using namespace std;
int cmp(char a,char b) //'A'<'a'<'B'<'b'<...<'Z'<'z'.
{
if(tolower(a)!=tolower(b))
return tolower(a)<tolower(b);
else
return a<b;
}
int main()
{
char ch[];
int n;
cin>>n;
while(n--)
{
scanf("%s",ch);
sort(ch,ch+strlen(ch),cmp);
do
{
printf("%s\n",ch);
}while(next_permutation(ch,ch+strlen(ch),cmp));
}
return ;
}
用next_permutation和prev_permutation求排列组合很方便,但是要记得包含头文件#include <algorithm>。
虽然最后一个排列没有下一个排列,用next_permutation会返回false,但是使用了这个方法后,序列会变成字典序列的第一个,如cba变成abc。prev_permutation同理。
【STL】全排列生成算法:next_permutation的更多相关文章
- C++ STL 常用算术和生成算法
C++ STL 常用算术和生成算法 accumulate() accumulate: 对指定范围内的元素求和,然后结果再加上一个由val指定的初始值. #include<numeric> ...
- C++进阶 STL(3) 第三天 函数对象适配器、常用遍历算法、常用排序算法、常用算数生成算法、常用集合算法、 distance_逆序遍历_修改容器元素
01昨天课程回顾 02函数对象适配器 函数适配器是用来让一个函数对象表现出另外一种类型的函数对象的特征.因为,许多情况下,我们所持有的函数对象或普通函数的参数个数或是返回值类型并不是我们想要的,这时候 ...
- STL中的算法
STL中的所有算法(70个) 参考自:http://www.cppblog.com/mzty/archive/2007/03/14/19819.htmlhttp://hi.baidu.com/ding ...
- generating permunation——全排列(算法汇总)
本文一共提供了4种全排列的方法,包括递归非字典序版本.递归字典序版本.标准库版本和BFS字典序版本,当然BFS非字典序实现相对于BFS字典序版本更加简洁,稍加修改即可. 说明:递归版本基于网上现有代码 ...
- C++ 凸包生成算法
由于我的极差记忆力,我打算把这个破玩意先记下来.因为以后会有改动(Delaunay三角网生成算法),我不想把一个好的东西改坏了... 好吧-- 凸包生成算法,: 1.先在指定的宽(width)高(he ...
- C++ STL 全排列函数
C++ 全排列函数...一听名字就在<algorithm>中... 首先第一个说的是next_permutation: #include <algorithm> bool n ...
- 一个UUID生成算法的C语言实现 --- WIN32版本 .
一个UUID生成算法的C语言实现——WIN32版本 cheungmine 2007-9-16 根据定义,UUID(Universally Unique IDentifier,也称GUID)在时 ...
- 分布式全局不重复ID生成算法
分布式全局不重复ID生成算法 算法全局id唯一id 在分布式系统中经常会使用到生成全局唯一不重复ID的情况.本篇博客介绍生成的一些方法. 常见的一些方式: 1.通过DB做全局自增操作 优点:简单.高 ...
- stl非变易算法(二)
这里接着上篇stl非变易算法(一)进行总结.主要解析算法函数count.count_if.mismatch.equal.search.search_n以及find_end.给出算法函数的实现及測试用例 ...
随机推荐
- 通过源码学Java基础:BufferedReader和BufferedWriter
准备写一系列Java基础文章,先拿Java.io下手,今天聊一聊BufferedReader和BufferedWriter BufferedReader BufferedReader继承Writer, ...
- SaltStack 最新版WebUI部署
saltstack web uiweb平台界面 saltapi项目主页:http://salt-api.readthedocs.org/en/latest/ halite 项目主页:https://g ...
- mysql一些写常用命令
参见pcttcnc2007博客腾飞 1.mysql的status信息命令: mysql> show global status; 2.可以列出mysql服务器运行各种状态值,另外,查询mysql ...
- TypeScript学习笔记(一):介绍及环境搭建
官网 TypeScript目前还在快速的发展中,当前的版本是1.6,有关TypeScript更多的信息可以在其官网中获取. http://www.typescriptlang.org/ 什么是Type ...
- sunlime text 3 快捷键总结
Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本. Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同文本进行同时编辑.举个栗子:快速选中并更改所有相同的变量名.函数名等. ...
- eclipse 插件
eclipse 插件 pdt(http://projects.eclipse.org/projects/tools.pdt/downloads) PHP Development Tools 3.2 R ...
- Windows 窗体的.Net 框架绘图技术
当编写一个典型的Windows 窗体程序时,窗体和控件的绘制.效果等操作是不需要特别加以考虑的.这是为什么呢?因为通过使用 .Net 框架,开发人员可以拖动一系列的控件到窗体上,并书写一些简单的与事件 ...
- delphi Sender和Tag的用法
var Form1: TForm1; SelectedColor:TColor;//clBlack; //Defaultimplementation{$R *.dfm}procedure TFor ...
- Android自己定义DataTimePicker(日期选择器)
Android自己定义DataTimePicker(日期选择器) 笔者有一段时间没有发表关于Android的文章了,关于Android自己定义组件笔者有好几篇想跟大家分享的,后期会记录在博客中.本篇 ...
- Select模型原理
Select模型原理 利用select函数,推断套接字上是否存在数据,或者是否能向一个套接字写入数据.目的是防止应用程序在套接字处于锁定模式时,调用recv(或send)从没有数据的套接字上接收数据, ...