C++ STL next_permutation()函数算法实现

1. next_permutation()函数

next_permutation函数原型为:

template
bool next_permutation (BidirectionalIterator first,
BidirectionalIterator last);
template <class BidirectionalIterator, class Compare>
bool next_permutation (BidirectionalIterator first,
BidirectionalIterator last, Compare comp);

该函数的功能是按照词典(或Compare comp函数)确定的顺序在原容器内生成[first, last)序列的下一个排列。如果下一个排列存在,函数将通过迭代器完成顺序调整,且返回值为true;否则,序列变为初始序列并且返回值为false。

比如:如果迭代器指向字符串“abcd”,经过next_permutation将返回true,并在原容器内给出“abdc”字符串。

next_permutation()函数在文字处理中非常实用。探究其算法原理也有助于我们加深对文字处理的理解。

2. next_permutation算法

实际上可以认为next_permutation截取的是全排列中的一个时刻。首先看看我们在做全排列时是怎么做的,有助于我们找到next_permutation的算法核心。比如,给定数字{1,2,3,4},下面按照顺序写出其全排列(数字无重用):

1234 //初始排列
1243 //交换3和4
1324 //交换2和3,并且重排3之后数字顺序
1342 //交换2和4
1423 //交换3和4,并且重排4之后数字顺序
1432 //交换2和3
2134 //交换1和2,并且重排2之后数字顺序
2143 //交换3和4
2314 //交换1和3,并且重排3之后数字顺序
2341 //交换1和4
2413 //交换3和4,并重排4之后数字顺序
2431 //交换1和3
3124 //交换2和3,并重排3之后数字顺序
3142 //交换2和4
3214 //交换1和2,并重排2之后数字顺序
3241 //交换1和4
3412 //交换2和4,并重排4之后数字顺序
3421 //交换1和2
4123 //交换3和4,并重排4之后数字顺序
4132 //交换2和3
4213 //交换1和2,并重排2之后数字顺序
4231 //交换1和3
4312 //交换2和3,并重排3之后数字顺序
4321 //交换1和2

总结上面的方法,我们在初始排列的基础上,每次从排列尾端着手,试图找到一对数字(i, j),满足条件{(i, j) | i<j},并交换其位置;有时候满足条件的数字对很多,我们总是按照以下顺序来操作:
1)比较最后两个数字,若满足,直接交换;
2)不满足,把排在前面一个数字纳入进来,分别用后面的数字与其比较(按照从后往前的顺序逐个比较,顺序很重要!),若有数字对满足要求,直接交换,然后前一个数字之后的所有数字排序;
3)如此循环往复,直到再也找不到一个数字比其后面的数字小,排列结束。

注意交换后的排序,其实在完成交换之后,前一个交换点以后的数字是按照降序排列的(否则之前就会发现一个逆序对满足条件{(i, j) | i<j}),因此排序只需要将前一个交换点之后的序列调转顺序(reverse函数),而不需要用sort函数。

上述算法其实就是next_permutation的算法,区别仅在于next_permutation只需找到下一个排列,而不用遍历所有排列。

下面以程序来实现。

3. 程序


                
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值