【C++】C++ STL中 next_permutation,prev_permutation函数的用法
目录
next_permutation和prev_permutation区别
next_permutation作用
产生全排列。 f(n)=n!
abc这个序列有六个可能的排列组合:abc,acb,bac,bca,cab,cba。
next_permutation和prev_permutation区别
next_permutation(start,end),和prev_permutation(start,end)。这两个函数作用是一样的,区别就在于前者求的是当前排列的下一个排列,后一个求的是当前排列的上一个排列。至于这里的“前一个”和“后一个”,我们可以把它理解为序列的字典序的前后,严格来讲,就是对于当前序列pn,他的下一个序列pn+1满足:不存在另外的序列pm,使pn<pm<pn+1.
对于next_permutation函数,其函数原型为:
#include <algorithm>
bool next_permutation(iterator start,iterator end)
abc这个序列有六个可能的排列组合:abc,acb,bac,bca,cab,cba。这些排列组合根据less-than操作符做字典顺序(lexicographical)的排序。也就是说,abc名列第一,因为每一个元素都小于其后的元素。acb是次一个排列组合,因为它是固定了a(序列内最小元素)之后所做的新组合。
同样道理,那些固定b(序列中次小元素)而做的排列组合,在次序上将先于那些固定c而做的排列组合。以bac和bca为例,bac在bca之前,因为次序ac小于序列ca。面对bca,我们可以说其前一个排列组合是bac,而其后一个排列组合是cab。序列abc没有“前一个”排列组合,cba没有“后一个”排列组合。
next_permutation()会取得[first,last)所标示之序列的下一个排列组合,如果没有下一个排列组合,便返回false;否则返回true。这个算法有两个版本。其中常用的版本使用元素型别所提供的less-than操作符来决定下一个排列组合。
用法举例
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int num[3]={1,2,3};
do
{
cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;
}while(next_permutation(num,num+3));
return 0;
}
输出结果为:
当我们把while(next_permutation(num,num+3))中的3改为2时,输出就变为了:
由此可以看出,next_permutation(num,num+n)函数是对数组num中的前n个元素进行全排列,同时并改变num数组的值。
另外,需要强调的是,next_permutation()在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数。比如,如果数组num初始化为2,3,1,那么输出就变为了:
对结构体num按照自定义的排序方式cmp进行排序
此外,next_permutation(node,node+n,cmp)可以对结构体num按照自定义的排序方式cmp进行排序。
也可以对字符…
next_permutation 自定义比较函数 POJ 1256
题目中要求的字典序是
//'A'<'a'<'B'<'b'<...<'Z'<'z'.
#include<iostream> //poj 1256 Anagram
#include<string>
#include<algorithm>
using namespace std;
int cmp(char a,char b)
{
if(tolower(a)!=tolower(b))//tolower 是将大写字母转化为小写字母.
return tolower(a)<tolower(b);
else
return a<b;
}
int main()
{
char ch[20];
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 0;
}
char 类型的next_permutation
int main()
{
char ch[205];
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 0;
}
//这样就不必事先知道ch的大小了,是把整个ch字符串全都进行排序
//若采用 while(next_permutation(ch,ch+5)); 如果只输入1562,就会产生错误,因为ch中第五个元素指向未知
//若要整个字符串进行排序,参数5指的是数组的长度,不含结束符
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;
}
}
参考:
https://blog.csdn.net/qian2213762498/article/details/79683905
https://blog.csdn.net/qq_43488547/article/details/100032724 《next_permutation(a,a+n)》