next_permutation 实现
2014-08-01 10:45
302 查看
之前实现的permutation一直是用数组(或者vector之类)的容器,然后递归出来的。面对要求快速求出next permutation的问题束手无策,今天看了STL中next_permution的实现,自己在没有看源码写一点吧。
SGI STL源码
#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; } } }
相关文章推荐
- 用STL的next_permutation算法实现全排列
- STL实现全排列 next_permutation
- 【C++ STL应用与实现】62: 如何使用std::next_permutation
- 全排列(一)next_permutation方式实现
- 自己实现了一下C++STL中的next_permutation,名为ant_next_permutation,发下代码
- next_permutation()函数实现全排序
- stl库之next_permutation实现全排列(二)
- C++标准库中next_permutation和pre_permutation实现原理
- poj3187(next_permutation实现全排列+杨辉三角)
- 面试OR笔试45——实现next_permutation
- C++ STL next_permutation的实现原理
- 九度OJ 1120 全排列 -- 实现C++STL中next_permutation()
- 详解STL中next_permutation()函数实现
- next_permutation实现原理
- 【leetcode】 Permutations 一个简单next_permutation的实现
- STL实现全排列 next_permutation
- STL算法之 next_permutation、prev_permutation 的原理和实现
- C++ STL之next_permutation小证明与Java实现
- next-permutation与prev-permutation及递归实现全排列
- 每天一道LeetCode-----重新实现next_permutation