在标准库算法中,next_permutation应用在数列操作上比较广泛.这个函数可以计算一组数据的全排列.但是怎么用,原理如何,我做了简单的剖析.

首先查看stl中相关信息.
函数原型:

template<class BidirectionalIterator>
   bool next_permutation(
      BidirectionalIterator _First
      BidirectionalIterator _Last
   );
template<class BidirectionalIterator, class BinaryPredicate>
   bool next_permutation(
      BidirectionalIterator _First, 
      BidirectionalIterator _Last,
      BinaryPredicate _Comp
   );

两个重载函数,第二个带谓词参数_Comp,其中只带两个参数的版本,默认谓词函数为"小于".

返回值:bool类型

分析next_permutation函数执行过程:

假设数列 d1,d2,d3,d4……

范围由[first,last)标记,调用next_permutation使数列逐次增大,这个递增过程按照字典序。例如,在字母表中,abcd的下一单词排列为abdc,但是,有一关键点,如何确定这个下一排列为字典序中的next,而不是next->next->next……

若当前调用排列到达最大字典序,比如dcba,就返回false,同时重新设置该排列为最小字典序。

返回为true表示生成下一排列成功。下面着重分析此过程:

根据标记从后往前比较相邻两数据,若前者小于(默认为小于)后者,标志前者为X1(位置PX)表示将被替换,再次重后往前搜索第一个不小于X1的数据,标记为X2。交换X1,X2,然后把[PX+1,last)标记范围置逆。完成。

要点:为什么这样就可以保证得到的为最小递增。

从位置first开始原数列与新数列不同的数据位置是PX,并且新数据为X2。[PX+1,last)总是递减的,[first,PX)没有改变,因为X2>X1,所以不管X2后面怎样排列都比原数列大,反转[PX+1,last)使此子数列(递增)为最小。从而保证的新数列为原数列的字典序排列next。

明白了这个原理后,看下面例子:

int main(){
 int a[] = {3,1,2};
do{
     cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
 while (next_permutation(a,a+3));
 return 0;
}

输出:312/321         因为原数列不是从最小字典排列开始。

所以要想得到所有全排列

int a[] = {3,1,2};   change to  int a[] = {1,2,3};

另外,库中另一函数prev_permutation与next_permutation相反,由原排列得到字典序中上一次最近排列。

所以

int main(){
 int a[] = {3,2,1};
do{
     cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
 while (prev_permutation(a,a+3));
 return 0;
}

才能得到123的所有排列。

本文转载于:http://blog.csdn.net/aipb2008/article/details/2227490

stl算法:next_permutation剖析的更多相关文章

  1. STL源代码剖析——STL算法stl_algo.h

    前言 在前面的博文中剖析了STL的数值算法.基本算法和set集合算法.本文剖析STL其它的算法,比如排序算法.合并算法.查找算法等等.在剖析的时候.会针对函数给出一些样例说明函数的使用.源代码出自SG ...

  2. stl源码剖析 详细学习笔记 算法总览

    //****************************基本算法***************************** /* stl算法总览,不在stl标准规格的sgi专属算法,都以 *加以标 ...

  3. STL源代码剖析——STL算法之set集合算法

    前言 本节介绍set集合的相关算法,各自是并集set_union,差集set_difference,交集set_intersection 和对称差集set_symmetric_difference.这 ...

  4. 《STL源码剖析》——第五、六:关联容器与算法

    第五章.关联容器  5.0.关联容器 标准的STL关联式容器分为set(集合)和map(映射表)两大类,以及这两大类的衍生体multiset(多键集合)和multimap(多键映射表).这些容器的底层 ...

  5. stl源码剖析 详细学习笔记 算法(1)

    //---------------------------15/03/27---------------------------- //算法 { /* 质变算法:会改变操作对象之值 所有的stl算法都 ...

  6. STL源码剖析——算法#1 内存处理基本工具

    我们在学习序列式容器时,我们经常会遇到这三个函数:uninitialized_copy.uninitialized_fill.uninitialized_fill_n.在那时我们只是仅仅知道这些函数的 ...

  7. 《STL源码剖析》相关面试题总结

    原文链接:http://www.cnblogs.com/raichen/p/5817158.html 一.STL简介 STL提供六大组件,彼此可以组合套用: 容器容器就是各种数据结构,我就不多说,看看 ...

  8. 面试题总结(三)、《STL源码剖析》相关面试题总结

    声明:本文主要探讨与STL实现相关的面试题,主要参考侯捷的<STL源码剖析>,每一个知识点讨论力求简洁,便于记忆,但讨论深度有限,如要深入研究可点击参考链接,希望对正在找工作的同学有点帮助 ...

  9. STL"源码"剖析-重点知识总结

    STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...

随机推荐

  1. C/C++之宏、内联函数和普通函数的区别

    内联函数的执行过程与带参数宏定义很相似,但参数的处理不同.带参数的宏定义并不对参数进行运算,而是直接替换:内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算 ...

  2. oracle中如何判断blob类型字段是否为空

    eg.假如有表T_GA_GRJBXX  ,字段zp是blob类型 查询blob非空的记录 SELECT * FROM u_rs_sjgx.T_GA_GRJBXX TB WHERE TB.zp IS n ...

  3. nginx反向代理-后端服务器组设置

    nginx服务器的反向代理时其最常用的重要功能之一,在实际工作中应用广泛,涉及的配置指令也比较多.下面会尽量详细地介绍对应的指令,及其使用状态. 反向代理一般是互联网需要向内网拉取资源,比如访问一个w ...

  4. Centos6版本使用yum报错 Loaded plugins: fastestmirror, refresh-packagekit, security Loading mirror speeds from cached hostfi Setting up Install Process No package gcc available. Error: Nothing to do

    在使用Centos6版本yum时报错 Loaded plugins: fastestmirror, refresh-packagekit, securityLoading mirror speeds ...

  5. 轻量级文本标记语言-Markdown

    Markdown简介 接触过github的都知道,在发布项目的时候可以建立一个说明文件README.md,这个md文件就是Markdown文本编辑语言的文件. Markdown 是一种轻量级标记语言, ...

  6. kafka调试遇到的问题

    在三台机器上以不同的端口部署了三个kafka和zookeeper实例,对应三套环境. 如: zk1:2181 zk2:2182 zk3:2183 kafka1:9092 kafka2:9093 kaf ...

  7. redis.windows.conf 参数说明

    1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程 daemonize no 2. 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/ru ...

  8. 20145337《网络对抗技术》Web安全基础实践

    20145337<网络对抗技术>Web安全基础实践 一.实验后回答问题 1.SQL注入攻击原理,如何防御 SQL注入攻击的本质是利用SQL语法,针对应用程序开发过程中的漏洞,从一个数据库获 ...

  9. 20145208 蔡野 《网络对抗》Exp4 恶意代码分析

    20145208 蔡野 <网络对抗>Exp4 恶意代码分析 问题回答 总结一下监控一个系统通常需要监控什么.用什么来监控. 监控一个系统通常需要监控这个系统的注册表,进程,端口,服务还有文 ...

  10. Python3基础 os listdir curdir pardir 查看工作目录及其上一级目录的所有文件名

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...