C++ STL next_permutation函数

在STL中,除了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的函数原型如下:

对于第二个重载函数的第三个参数,默认比较顺序为小于。如果找到下一个序列,则返回真,否则返回假。

函数实现原理如下:

在当前序列中,从尾端往前寻找两个相邻元素,前一个记为*i,后一个记为*ii,并且满足*i < *ii。然后再从尾端寻找另一个元素*j,如果满足*i < *j,即将第i个元素与第j个元素对调,并将第ii个元素之后(包括ii)的所有元素颠倒排序,即求出下一个序列了。

代码实现如下:

 1 template<class BidirectionalIterator>
 2 bool next_permutation(
 3       BidirectionalIterator first,
 4       BidirectionalIterator last
 5 )
 6 {
 7     if(first == last)
 8         return false; //空序列
 9
10     BidirectionalIterator i = first;
11     ++i;
12     if(i == last)
13         return false;  //一个元素,没有下一个序列了
14
15     i = last;
16     --i;
17     for(;;) {
18         BidirectionalIterator ii = i;
19         --i;
20         if(*i < *ii) {
21             BidirectionalIterator j = lase;
22             while(!(*i < *--j));
23
24             iter_swap(i, j);
25             reverse(ii, last);
26             return true;
27         }
28         if(i == first) {
29             reverse(first, last);  //全逆向,即为最小字典序列,如cba变为abc
30             return false;
31         }
32     }
33 }

上个例子

 1 // next_permutation example
 2 #include <iostream>     // std::cout
 3 #include <algorithm>    // std::next_permutation, std::sort
 4
 5 int main () {
 6   int myints[] = {1,2,3};
 7
 8   std::sort (myints,myints+3);
 9
10   std::cout << "The 3! possible permutations with 3 elements:\n";
11   do {
12     std::cout << myints[0] << ‘ ‘ << myints[1] << ‘ ‘ << myints[2] << ‘\n‘;
13   } while ( std::next_permutation(myints,myints+3) );
14
15   std::cout << "After loop: " << myints[0] << ‘ ‘ << myints[1] << ‘ ‘ << myints[2] << ‘\n‘;
16
17   return 0;
18 }
The 3! possible permutations with 3 elements:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
After loop: 1 2 3

具体应用可参考:字符串的排列

时间: 2024-10-06 13:04:17

C++ STL next_permutation函数的相关文章

[OI - STL] next_permutation( ) &amp; prev_permutation( )函数

next_permutation( ) 和 prev_permutation( ) 函数基本类似,都需要用到头文件名<algorithm> next_permutation()函数 用法:next_permutation(first,last) 作用:next_permutation()函数将 [ first , last ] 区间中的序列转换为字典序的下一个排列.如果下一个排列存在返回true,如果下一个排列不存在(即区间中包含的是字典序的最后一个排列),则该函数返回false,并将区间转换

STL next_permutation排列

概念 全排列的生成算法有很多种,有递归遍例,也有循环移位法等等.C++/STL中定义的next_permutation和prev_permutation函数则是非常灵活且高效的一种方法,它被广泛的应用于为指定序列生成不同的排列.本文将详细的介绍prev_permutation函数的内部算法. 按照STL文档的描述,next_permutation函数将按字母表顺序生成给定序列的下一个较大的序列,直到整个序列为减序为止.prev_permutation函数与之相反,是生成给定序列的上一个较小的序列

打印全排列和stl::next_permutation

打印全排列是个有点挑战的编程问题.STL提供了stl::next_permutation完美的解决了这个问题. 但是,如果不看stl::next_permutation,尝试自己解决,怎么做? 很自然地,使用递归的办法: 1. 单个元素的排列只有1个. 2. 多个元素的排列可以转化为: 以每个元素为排列的首个元素,加上其他元素的排列. 有了思路,就可以编码了. 第一个版本: void printAllPermutations(const std::string& prefix, int set[

STL next_permutation 算法原理和自行实现

目标 STL中的next_permutation 函数和 prev_permutation 两个函数提供了对于一个特定排列P,求出其后一个排列P+1和前一个排列P-1的功能. 这里我们以next_permutation 为例分析STL中实现的原理,prev_permutation 的原理与之类似,我们在最后给出它们实现上差异的比较 问题: 给定一个排列P,求出其后一个排列P+1是什么. 思路 按照字典序的定义不难推出,正序,是一组排列中最小的排列,而逆序,则是一组排列中最大的排列. 从字典序的定

next_permutation 函数

STL的next_permutation函数可以求出某个特定序列的下一个排列,当然,如果对一个给定序列,排序之后可以轻松求出全排列...... 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<map> 7 #include<set> 8 #includ

全排列问题(next_permutation函数)

D的小L 时间限制:4000 ms  |  内存限制:65535 KB 难度:2 描述       一天TC的匡匡找ACM的小L玩三国杀,但是这会小L忙着哩,不想和匡匡玩但又怕匡匡生气,这时小L给匡匡出了个题目想难倒匡匡(小L很D吧),有一个数n(0<n<10),写出1到n的全排列,这时匡匡有点囧了,,,聪明的你能帮匡匡解围吗? 输入 第一行输入一个数N(0<N<10),表示有N组测试数据.后面的N行输入多组输入数据,每组输入数据都是一个整数x(0<x<10) 输出 按

HDOJ 1027 Ignatius and the Princess II - next_permutation函数

Ignatius and the Princess II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5447    Accepted Submission(s): 3198 Problem Description Now our hero finds the door to the BEelzebub feng5166. He o

白话 STL next_permutation 原理

翻译自stackoverflow 英语好的同学可以自己去看一下. 什么是next permutation 下面是四个元素{1,2,3,4}的排列 1 2 3 4 1 2 4 3 1 3 2 4 1 3 4 2 1 4 2 3 1 4 3 2 2 1 3 4 ... 每一行都是一个排列. 我们如何从一个排列转到下一个排列呢?我们可以将如上4个数的排列当做一个数.每一个数的下一个排列就是发现下一个比它大的数. next_permutation就是寻找这些元素所组成的数字的升序排列中的下一个数. 比较

《STL源码剖析》--next_permutation函数

STL中提供了2个计算排列组合关系的算法.分别是next_permucation和prev_permutaion. next_permutation是用来计算下一个(next)字典序排列的组合,而prev_permutation用来计算上一个(prev)字典序的排列组合. 字典排序是指排列组合中,按照大小由小到大的排序,例如123的排列组着,字典排序为123,132,213,231,312,321. 看一下next_permutation的实现原理: 从序列的后面向前找,找了两个相邻的元素p[n