/// @brief 取得[first, last)所标示序列的下一个排列组合,如果没有下一个排序组合,返回 false,否则返回 true template <classBidirectionalIterator> boolnext_permutation(BidirectionalIterator first, BidirectionalIterator last){ auto i = last; if (first == last || first == --i) returnfalse; for (;;) { // 从尾部向前查找 auto ii = i; // 找到相邻元素满足 *i < *ii if (*--i < *ii) { // 从尾部向前查找第一个大于 *i 的元素 *j auto j = last; while (!(*i < *--j)) {} // 交换 *i 和 *j tinystl::iter_swap(i, j); // 将 ii 之后的元素颠倒排列 tinystl::reverse(ii, last); returntrue; } if (i == first) { // 进行到这里时,当前序列已经是“最后一个”排列组合, // 将整个序列逆向排列,使其成为“第一个”排列组合 tinystl::reverse(first, last); returnfalse; } } }
/// @brief 重载版本使用函数对象 comp 代替比较操作 template <classBidirectionalIterator, classCompare> boolnext_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp){ auto i = last; if (first == last || first == --i) returnfalse; for (;;) { auto ii = i; if (comp(*--i, *ii)) { auto j = last; while (!comp(*i, *--j)) {} tinystl::iter_swap(i, j); tinystl::reverse(ii, last); returntrue; } if (i == first) { tinystl::reverse(first, last); returnfalse; } } }
/// @brief 取得[first, last)所标示序列的上一个排列组合,如果没有上一个排序组合,返回 false,否则返回 true template <classBidirectionalIterator> boolprev_permutation(BidirectionalIterator first, BidirectionalIterator last){ auto i = last; if (first == last || first == --i) returnfalse; for (;;) { // 从尾部向前查找 auto ii = i; // 找到第一对相邻元素,满足 *i > *ii if (*ii < *--i) { // 从尾部向前查找第一个小于 *i 的元素 *j auto j = last; while (!(*--j < *i)) {} // 交换 *i 和 *j tinystl::iter_swap(i, j); // 将 ii 之后的元素颠倒排列 tinystl::reverse(ii, last); returntrue; } if (i == first) { // 进行到这里时,当前序列已经是“第一个”排列组合, // 将整个序列逆向排列,使其成为“最后一个”排列组合 tinystl::reverse(first, last); returnfalse; } } }
/// @brief 重载版本使用函数对象 comp 代替比较操作 template <classBidirectionalIterator, classCompare> boolprev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp){ auto i = last; if (first == last || first == --i) returnfalse; for (;;) { auto ii = i; if (comp(*ii, *--i)) { auto j = last; while (!comp(*--j, *i)) {} tinystl::iter_swap(i, j); tinystl::reverse(ii, last); returntrue; } if (i == first) { tinystl::reverse(first, last); returnfalse; } } }