next_permutation 实现

来源:互联网 发布:java大视频断点续传 编辑:程序博客网 时间:2024/06/09 19:12

之前实现的permutation一直是用数组(或者vector之类)的容器,然后递归出来的。面对要求快速求出next permutation的问题束手无策,今天看了STL中next_permution的实现,自己在没有看源码写一点吧。


#include <iostream>#include <vector>#include <string>/* 算法的主要思想    以数组 0 1 2 4 3 为例    1. 从最末元素开始往前查找,找到第一对元素(第一个即为i,第二记为ii),       使*i < *ii,在本例为元素对 2 4    2. 从尾部开始往前查找,找出第一个大于i元素的值,记为j,此处为3    3. 然后交换i和j的元素,再将ii后的元素(含ii)逆置,即可得next permutaioin       例子的结果为 0 1 3 2 4*/template <typename T>bool next_permutation (typename std::vector<T>::iterator first, typename std::vector<T>::iterator last){    typename std::vector<T>::iterator i, ii, j;    // 1. find the last pair of i and ii, let *i < *ii    ii = last - 1;    if (ii == first || first == last) // only 1 element or empty, done        return false;    i = ii - 1;    for (; *i > *ii; )    {        ii = i;        if (ii == first) // the next permutaion is not exist            return false;        -- i;    }    // found the pair    // 2. find the j    for (j = last - 1; j >= i && *j < *i; --j);    // 3. swap i and j    {        T tmp = *i;        *i = *j;        *j = tmp;    }    // reverse ii - j    while(j > ii)    {        T tmp = *j;        *j = *ii;        *ii = tmp;        -- j;        ++ ii;    }    return true;}template <typename T>void show(const typename std::vector<T> &v){    for (typename std::vector<int>::const_iterator i = v.begin(); i != v.end(); ++ i)    {        std::cout << *i << " ";    }    std::cout << std::endl;}int main(){    int a[] = {0, 1, 2, 4, 3};    std::vector<int> va(a, a + sizeof(a) / sizeof(a[0]));    show<int>(va);    if (next_permutation<int>(va.begin(), va.end()))    {        show<int>(va);    }    int b[] = {4, 3, 2};    std::vector<int> vb(b, b + sizeof(b)/sizeof(b[0]));    show<int>(vb);    if (next_permutation<int>(vb.begin(), vb.end()))    {        show<int>(vb);    }    else    {        std::cout << "There is no next permutation!" << std::endl;    }    return 0;}


SGI STL源码

// next_permutation and prev_permutation, with and without an explicitly // supplied comparison function.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)    return false;  _BidirectionalIter __i = __first;  ++__i;  if (__i == __last)    return false;  __i = __last;  --__i;  for(;;) {    _BidirectionalIter __ii = __i;    --__i;    if (*__i < *__ii) {      _BidirectionalIter __j = __last;      while (!(*__i < *--__j))        {}      iter_swap(__i, __j);      reverse(__ii, __last);      return true;    }    if (__i == __first) {      reverse(__first, __last);      return false;    }  }}


0 0
原创粉丝点击