今天想学学全排列的非递归实现,但是搜索了半天,都是转载的同一篇文章,这篇文章的规律我还是没看懂。
想到c++的STL里有一个next_permutation()可以实现产生比当前序列大一点的下一个序列。
通过这种方法,也可以实现全排列的非递归实现。
STL源码下载:http://www.sgi.com/tech/stl/download.html
next_permutation()的原函数位于:stl_alog.h里面
内容如下:
// 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;
}
}
}
基本思想如下:
从最后每相邻的两个进行比较,如果有前面一个比后面的小(i为较小位置,ii,为较大位置),那么此时一定存在一个排列比当前的大,然后是怎么产生这下一个排列。应该找这个较小的数的后面从最后开始比它大的第一个数,将它换到当前较小的位置上,然后将较大数ii到最后进行逆序。这样就产生了下一个排列。原理类似于,找到下一个较大的作为开始位的数,然后将后面的数字从最小开始即升序,例如原来为4653转换后为:5346
next_permutation()
{
if no element || only one element
return false;
i = last_element_ptr
while(true)
{
ii = i; // the element before i
--i;
if *i < *ii // then there must be a sequence to change
{
j = last_element_ptr
while( !(*i<*--j) //find the first element from tail to head
{} //which is bigger than *i
swap(i, j) // swap the elements which i and j point to.
reverse(ii, last_element_ptr) // reverse the array
return true;
}
if i == first_element_ptr // if we to the head of the array, so no permutation
{
reverse(first_element_ptr, last_element_ptr)
return false
}
}
}
从stl的next_permutation源码中我们看到,对于一个已经是最大权值的序列(即没有下一个比当前值大的排列),虽然返回值是false,但是它仍就将序列进行了逆序,例如对4321使用next_permutation后,序列变为1234.
看来读读久经考验的源代码是大有好处的。
由此,我们就可以实现非递归的全排列了。呵呵 ,不用多说了吧。
分享到:
相关推荐
next_permutation 函数是 C++/STL 中定义的函数之一,它可以生成给定序列的下一个较大的排列。prev_permutation 函数则是生成给定序列的上一个较小的排列。二者的原理相同,仅遍例顺序相反。 为了生成下一个较大的...
本PDF书籍深入分析了STL(标准模板库)的各项特性和源码实现,涵盖了类型技术、内存管理、常见算法与数据结构等内容,具体讲解了一系列高级实现技术如STL各种容器(如向量、列表、树、队列等)、RB树结构以及众多...
6.7.5 next_permutation 380 6.7.6 prev_permutation 382 6.7.7 random_shuffle 383 6.7.8 partial_sort / partial_sort_copy 386 6.7.9 sort 389 6.7.10 equal_range(应用于有序区间) 400 6.7.11 inplace_...
- 使用`std::next_permutation`函数生成所有可能的排列组合。 - 输出所有合法的仓库访问序列。 3. **代码实现**(示例代码片段): ```cpp #include #include #include using namespace std; int main...
通过对以上两个代码示例的分析,我们可以看到STL提供的工具不仅方便高效,而且功能强大。无论是向量容器的操作还是全排列的生成,都展示了STL的强大能力及其在实际编程中的应用价值。掌握这些技术对于提高编程效率、...
6.7.5 next_permutation 380 6.7.6 prev_permutation 382 6.7.7 random_shuffle 383 6.7.8 partial_sort / partial_sort_copy 386 6.7.9 sort 389 6.7.10 equal_range(应用于有序区间) 400 6.7.11 inplace_...
第5章 C++ STL泛化技术分析 58 5.1 算法和迭代器 58 5.1.1 算法 58 5.1.2 迭代器 61 5.1.3 函数对象 65 5.1.4 适配器 68 5.2 内存分配器和容器 74 5.2.1 内存分配器 75 5.2.2 容器 77 5.3 概念 ...
第5章 C++ STL泛化技术分析 58 5.1 算法和迭代器 58 5.1.1 算法 58 5.1.2 迭代器 61 5.1.3 函数对象 65 5.1.4 适配器 68 5.2 内存分配器和容器 74 5.2.1 内存分配器 75 5.2.2 容器 77 5.3 概念 ...
第5章 C++ STL泛化技术分析 58 5.1 算法和迭代器 58 5.1.1 算法 58 5.1.2 迭代器 61 5.1.3 函数对象 65 5.1.4 适配器 68 5.2 内存分配器和容器 74 5.2.1 内存分配器 75 5.2.2 容器 77 5.3 概念 ...
在C++中,标准模板库(STL)提供了next_permutation()函数,可以用来直接生成下一个排列,极大地方便了排列组合的算法实现。 对于时间复杂度,全排列算法至少是O(n!)的复杂度,因为需要生成所有可能的排列组合。...
而使用非递归的STL库函数`next_permutation`,它通过迭代方式避免了重复计算,直接生成下一个排列,时间复杂度为O(n*n!),在实际操作中,对于较大的n,非递归方法通常比递归方法更快。5、实验体会递归算法虽然在逻辑...
18. next_permutation和prev_permutation:改变序列的排列顺序到下一个或上一个排列。 19. nth_element:重新排序序列,使得第n个位置的元素是它最终排序位置的元素。 20. partial_sort和partial_sort_copy:对...
同时,我们可以利用C++的迭代器或者算法库中的函数,如next_permutation,来生成和处理全排列。 接下来,"one.cpp"的代码可能包含以下步骤: 1. 创建一个大小为256的vector,初始化为0到255的序列。 2. 使用next_...
40.6 一个简单的表达式分析器 40.7 向分析器中添加变量 40.8 递归下降分析器中的语法检查 40.9 构建一个通用的分析器 40.10 需要试验的一些东西 附录A C++的.NET可管理扩展 附录B C++和机器人时代
- 示例:`std::next_permutation(begin(v), end(v));` 7. **分割(Partition)**: - 功能:根据谓词将元素重新排列成两个部分。 - 示例:`std::partition(begin(v), end(v), predicate);` 8. **随机排列...
- **下一个排列**:`next_permutation()`。 - **次序元素**:`nth_element()`。 - **部分排序**:`partial_sort()`。 - **部分排序拷贝**:`partial_sort_copy()`。 - **部分累加**:`partial_sum()`。 - **前一个...
- **next_permutation()/nth_element()**:用于生成序列的下一个排列、将第n个元素放在正确位置等。 - **partial_sort()/partial_sort_copy()**:用于部分排序序列或拷贝序列的一部分。 - **partial_sum()/prev_...