C++ next_permutation 源码分析
来源:互联网 发布:软件测试压力测试 编辑:程序博客网 时间:2024/06/07 10:24
template<class _BidIt> inlinebool _Next_permutation(_BidIt _First, _BidIt _Last){ // permute and test for pure ascending, using operator<//-----------------------------------------------\_DEBUG_RANGE(_First, _Last);_BidIt _Next = _Last;if (_First == _Last || _First == --_Next) return (false);//上面这一块是检查边界范围的//-----------------------------------------------/for (; ; ) { // find rightmost element smaller than successor _BidIt _Next1 = _Next; if (_DEBUG_LT(*--_Next, *_Next1)) { // swap with rightmost element that's smaller, flip suffix _BidIt _Mid = _Last; for (; !_DEBUG_LT(*_Next, *--_Mid); ) ; std::iter_swap(_Next, _Mid);//本身带的注释已经说得很明白,从最右边开始比较两两相邻的元素,直至找到右边比左边大的一对,左边那个//就是将要被替换的,再从最右边开始找比这个元素大的第一个,交换他们两个 std::reverse(_Next1, _Last);//交换之后,翻转交换元素的后面的所有元素 return (true); } if (_Next == _First) { // pure descending, flip all std::reverse(_First, _Last); return (false); } }}
关键是确定一个排列的下一个排列是什么,我看着明白却说不明白,于是转贴一段,以下来自 http://www.cppblog.com/yindf/archive/2010/02/24/108312.html
abcd next_permutation -> abdc
那么,为什么abcd的下一个是abdc而不是acbd呢?
说简单一点,用 1,2,3,4 代替 a,b,c,d,可以得到:
原排列 中间转换 值
1,2,3,4 3,2,1 ((3 * (3) + 2) * (2) + 1) * (1) = 23
1,2,4,3 3,2,0 ((3 * (3) + 2) * (2) + 0) * (1) = 22
1,3,2,4 3,1,1 ((3 * (3) + 1) * (2) + 1) * (1) = 21
1,3,4,2 3,1,0 ((3 * (3) + 1) * (2) + 0) * (1) = 20
1,4,3,2 3,0,1 ((3 * (3) + 0) * (2) + 1) * (1) = 19
. . .
. . .
. . .
4,3,2,1 0,0,0 ((0 * (3) + 0) * (2) + 0) * (1) = 0
| | | | | |
| | | |
| |
上面的中间转换指的是:每一个数字后面比当前位数字大的数字的个数。比如:
1,3,4,2 中,1 后面有(3, 4, 2) 他们都大于1,所以第一位是 3
3 后面有(4, 2), 但只有4大于3,所以第二位是 1
4 后面有(2), 没有比4 大的,所以第三位是 0
最后一位后面肯定没有更大的,所以省略了一个0。
经过这种转换以后,就得到了一种表示方式(中间转换),这种表达方式和原排列一一对应,可以相互转化。
仔细观察这种中间表达方式,发现它的第一位只能是(0,1,2,3),第二位只能是(0,1,2),第三位只能是(0,1)。通常,数字是用十进制表示的,计算机中用二进制,但是现在,我用一种特殊的进制来表示数:
第一位用1进制,第二位用2进制。。。
于是就得到了这种中间表示方式的十进制值。如:
阶
| | |
1,1,0 ----> ((1 * (3) + 1) * (2) + 0) * (1) = 8
3,1,0 ----> ((3 * (3) + 1) * (2) + 0) * (1) = 20
现在排列数和有序的十进制数有了一一对应的关系(通过改变对应关系,可以使十进制数升序)。
- C++ next_permutation 源码分析
- C++ next_permutation 源码分析
- 对范型算法next_permutation的源码分析
- next_permutation的源码认识。
- C++/C源码分析
- C++STL的next_permutation
- C++STL的next_permutation
- C++STL的next_permutation
- [C++]next_permutation()函数解析
- 《STL源码剖析》--next_permutation函数
- syscore.c 源码分析
- C-Ruby源码分析
- word2vec.c源码分析
- ngx_rtmp_notify_module.c 源码分析
- helloworld.c源码分析
- next_permutation
- next_permutation
- next_permutation
- Recording DirectX and OpenGL Rendered Animations
- asp.net实现文件夹及文件压缩,并实现下载(三)——文件超过150M
- HandlerSocket的优势和缺陷阐述
- [c#中的xml操作]-------1、新建xml文件并添加结点
- 如何解决TIME_WAIT过多的解决办法(附Socket中的TIME_WAIT状态详解)
- C++ next_permutation 源码分析
- 《玩转.NET Micro Framework 移植-基于STM32F10x处理器》资源汇总
- Linux 文件内容大小写转换
- UBUNTU添加开机自动启动程序方法
- Objective-C的self.用法的一些总结
- 在一个Activity中使用多个Dialog
- ShoppingMall客户端改进计划
- windows 2003无法播放flv
- java.util.Queue接口add()和remove(),add()和remove(),element()或者peek()区别