next_permutation

来源:互联网 发布:nba2k17帅哥捏脸数据 编辑:程序博客网 时间:2024/05/29 23:48

next_permutation生成下一个排列。
prev_permutation生成上一个排列。
例如,1 2 4 3 的下一个排列是1 3 2 4,上一个队列是1 2 3 4.

next_permutation是如何实现的呢?
例如对于7 6 5 1 4 3 2,它下一个排列是 7 6 5 2 1 3 4。发现下一个排列1之前的元素是不用改变的,并且1的位置后边都是从大到小排列的,1的位置应该由2代替(从后往前第一个大于1的元素),交换之后是7 6 5 2 4 3 1,注意4 3 1 是从大到小,变为从小到大就好了。

next_permutation一个相反的过程,请看注释。

template <class _BidirectionalIter>bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {    __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator);    __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type,        _LessThanComparable);    if (__first == __last)//if empty        return false;    _BidirectionalIter __i = __first;    ++__i;    if (__i == __last)//if only one item        return false;    __i = __last;    --__i;//指向尾元素    for (;;)    {        _BidirectionalIter __ii = __i;// i和ii是相邻的关系        --__i;        if (*__i < *__ii) //说明ii后边的都是从大到小排的。        {            _BidirectionalIter __j = __last;            while (!(*__i < *--__j))//找到第一个比*i小的,交换            {            }            iter_swap(__i, __j);            reverse(__ii, __last);//把上边从大到小变为从小到大            return true;        }        if (__i == __first) //已经是最后一个排列        {            reverse(__first, __last);            return false;        }    }}template <class _BidirectionalIter>bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {    __STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator);    __STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type,        _LessThanComparable);    if (__first == __last)        return false;    _BidirectionalIter __i = __first;    ++__i;    if (__i == __last)        return false;    __i = __last;    --__i;    for (;;)     {        _BidirectionalIter __ii = __i;        --__i;        if (*__ii < *__i) //说明ii后边的都是从小到大排的。        {            _BidirectionalIter __j = __last;            while (!(*--__j < *__i))            {            }            iter_swap(__i, __j);            reverse(__ii, __last);//把上边从小到大变为从大到小            return true;        }        if (__i == __first)         {            reverse(__first, __last);            return false;        }    }}