next_permutation函数

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

int main()
{
    for(string s;cin>>s;)
    {
        if(s.empty())
            continue;
        if(s.length()<=1)
            cout<<"No more permuntion"<<endl;
        
        //ele_left右边最大减序子集左边相邻的一个元素 
        string::iterator ele_left=s.end(),ele_right;
        for(--ele_left;ele_left!=s.begin();--ele_left)//查找右边最大的减序子集
            if(*(ele_left-1)<*ele_left) 
                break;
        
        if(ele_left==s.begin())
            cout<<"No more permuntion"<<endl;
        
        ele_left--;
        for(ele_right=ele_left+1;ele_right!=s.end();++ele_right)
            if(*ele_right<*ele_left)
                break;
    
        //交换iPivot和iNewHead的值,但不改变它们的指向
        iter_swap(ele_left,--ele_right);
        reverse(ele_left+1,s.end());//反转右侧减序子集,使之成为最小的增序子集
        cout<<s<<endl;
    }
    return 0;
}

next_permutation函数将按字母表顺序生成给定序列的下一个较大的排列,直到整个序列为降序为止。prev_permutation函数与之相反,是生成给定序列的上一个较小的排列。

二者原理相同,仅遍例顺序相反,这里仅以next_permutation为例介绍算法。
先对序列大小的比较做出定义:两个长度相同的序列,从两者的第一个元素开始向后寻找,直到出现一个不同元素(也可能就是第它们的第一个元素)

该元素较大的序列为大,反之序列为小;若一直到最后一个元素都相同,那么两个序列相等。

复杂度
最好的情况为pn的最后的2个元素构成一个最小的增序子集,交换次数为1,复杂度为O(1),最差的情况为1个元素最小,而后面的所有元素构成减序子集,这样需要先将第1个元素换到最后,

然后反转后面的所有元素。交换次数为1+(n-1)/2,复杂度为O(n)。这样平均复杂度即为O(n/2)。

参考链接:https://jingyan.baidu.com/article/63acb44a90370061fcc17e18.html?qq-pf-to=pcqq.c2c

猜你喜欢

转载自www.cnblogs.com/tianzeng/p/9151631.html