首先,permutation指的是对元素的重排,比方a , b , c 三个元素的全部的重排为    abc, acb, bac,bca,cab,cba 总共 3!  = 6 中情况,可是怎样声称这六种情况呢,C++标准库定义了函数 next_permutation,来生成一组元素的全部的全排列。

首先。了解该函数的声明以及实现:

函数声明为: [摘自 www.cplusplus.com]

std::next_permutation

default (1)
template <class BidirectionalIterator>
bool next_permutation (BidirectionalIterator first,
BidirectionalIterator last);
custom (2)
template <class BidirectionalIterator, class Compare>
bool next_permutation (BidirectionalIterator first,
BidirectionalIterator last, Compare comp);

此两者在C++的标准库中被实现为模板的形式。

參数说明:

first last  
当中的迭代器  first 和 last 用来表示元素的范围 [ first, last ) 不正确称边界。

再来就是该迭代器的类型为双向迭代器。那么也就是说 随机迭代器和双向迭代器能够作为该函数的參数传入。

Compare comp   是用来比較的函数,也就是说用来决定生成的重排的顺序函数。默认使用的是opeartor<符号,当然你自己也能够定义自己的比較函数,作为函数指针传入。或者是定义仿函数,传入函数对象,

返回值:

假设在该comp函数下。下一个重拍序列存在。则返回true。走则返回false,也就是说这一次的重拍序列已经是最后一个重排序列了。

比方,假设採用的是operator<作为比較函数的话,那么 {1,2,3}的最后一个重排就是321,第一个重排就是123,在321之后再调用next_premutation,返回false,可是该函数会将原来的数组排列为 1,2,3。

副作用:

该函数会改动传入的元素顺序。


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

运行结果为:

能够看出,该函数会自己主动在当前的元素的顺序基础上。生成兴许的排列。也就是说。假设要生成全部的permutation的话,那么须要先将元素排序。

  OK!!

使用方法已经具体解释了。接下来便是要将该函数的真面目示人了。

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中的版本号,该函数实现原理例如以下:

在当前的序列中,从尾端出发往前找到一对相邻的元素  a[ i ] 与 a[ j ] ,使得 a[ i ]  < a[ j ], (此处默认採用less函数对象)。然后再从尾端出发找到一个字符
 a[ k ] ,使得 a[ i ]  < a[ k ], 此时交换 a[ k ] 与 a[ i ], 而且将a[ j --- end) 之间的全部元素逆序就可以。代码实现为:

template<class bidirectional_iterator>
bool permutation(bidirectional_iterator first, bidirectional_iterator last)
{
if(first == last) return false; //假设没有元素 if(first + 1 == last) return false; //假设仅仅有一个元素 bidirectional_iterator j = last;
--j; while(1)
{
bidirectional_iterator i = j;
--i;
//find a[i] < a[j] and they are adjacent
if(*i < *j)
{
bidirectional_iterator k = last;
while(!(*i < *--k)){}
std::iter_swap(i,k); //或者是 swap(*i, *k);
std::reverse(j,last);
return true;
}
--j;
//no such a[i] < a[i+1] pair found
if( j == first)
{
//restore the first of the permutation
std::reverse(first, last);
return false;
}
}
}

上述代码中的swap函数必须是iter_swap函数。利用swap仅仅是交换了迭代器的指针,并未实际改变元素的位。也能够使用swap(*i, *k);

关于该函数的comp对象的实际形式,接着会有一篇关于函数指针以及函数对象的博文,具体解说。

2014 5.18 更新版本号

看到网上的一篇文章的求解全排列:

假设仅仅须要直接返回全部的全排列的话,那么非常easy,依次交换字符串中的相邻的字符就可以。

例如以下图:

C++ 标准库 permutation的更多相关文章

  1. Python标准库笔记(10) — itertools模块

    itertools 用于更高效地创建迭代器的函数工具. itertools 提供的功能受Clojure,Haskell,APL和SML等函数式编程语言的类似功能的启发.它们的目的是快速有效地使用内存, ...

  2. Python标准库--typing

    作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 模块简介 Python 3.5 增加了一个有意思的库--typ ...

  3. PHP SPL(PHP 标准库)

    一.什么是SPL? SPL是用于解决典型问题(standard problems)的一组接口与类的集合.(出自:http://php.net/manual/zh/intro.spl.php) SPL, ...

  4. C 标准库系列之locale.h

    locale.h 区域设置相关,主要针对时间日期.货币格式.字符控制.数字格式等以满足某区域的设置需要. locale设置类别主要包括以下几个宏定义的类别: LC_ALL:设置所有的类别: LC_CO ...

  5. C 标准库系列之errno.h

    errno.h 提供了一个整数全局变量errno,当系统调用或者库函数的错误事件发生时可能会修改该值,指明错误的原因,该值可在任何需要的地方被修改:一般情况不为0的值表示出现了异常或者错误. errn ...

  6. C 标准库系列之assert.h

    先简单介绍一下<assert.h>头文件,该头文件的目的便是提供一个宏assert的定义,即可以在程序必要的地方使用其进行断言处理:断言在程序中的作用是当在调试模式下时,若程序给出的前提条 ...

  7. C 标准库系列之概述

    基本上很多编程语言都会提供针对语言本身的一系列的标准库或者包,当然C语言同样也有提供标准库,C语言的标准库是一系列的头文件的集合:如assert.h.ctype.h.errno.h.float.h.l ...

  8. C标准库-数值字符串转换与内存分配函数

    原文链接:http://www.orlion.ga/977/ 一.数值字符串转换函数 #include <stdlib.h> int atoi(const char *nptr); dou ...

  9. Python标准库13 循环器 (itertools)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在循环对象和函数对象中,我们了解了循环器(iterator)的功能.循环器是对象的 ...

随机推荐

  1. Ajax的简单基础

    什么是 AJAX ? AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新. 这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行 ...

  2. 引爆潮流技术 Vue+Django REST framework打造生鲜电商项目

    引爆潮流技术Vue+Django REST framework打造生鲜电商项目 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受, ...

  3. Python学习之字典--三级菜单

    效果图: 实现代码: dic = { '人物':{ '帽子':{'前年玄铁帽'}, '武器':{'屠龙宝刀'} }, '属性':{ '力量':{35}, '敏捷':{66} }, '任务':{ '主线 ...

  4. SpringBooot- 访问时,默认有弹出认证

    SpringBooot- 访问时,默认有弹出认证 springboot启动成功后,访问请求时,默认弹出窗口,需登录认证. 原因: 是由于使用了springsecurity的默认安全策略,解决方案:启动 ...

  5. .NET2.0引用.NET3.5的System.Core.dll&Dapper在.NET2.0下的配置

    微软MSDN对.NET2.0,3.0,3.5的描述: .NET Framework 版本 2.0.3.0 和 3.5 是使用同一 CLR 版本 (CLR 2.0) 生成的. 这些版本表示单个安装的连续 ...

  6. c++新特性实验(5)声明与定义:属性列表(C++11 起)

    1.初识属性 1.1 实验A: noreturn 属性 [[ noreturn ]] static void thread1(void *data){ cout << "nore ...

  7. django模块安装环境变量

    django 模块 一 安装: 方法一: (在 JetBrains PyCharm 2017.2 软件的) 设置 (里找到) 项目:python +(添加) (搜索) django Install p ...

  8. Vue-cli3.x在开发环境中(router采用 history模式)出现Failed to resolve async component default: Error: Loading chunk {/d} failed.或者Uncaught SyntaxError: Unexpected token <错误

    使用Vue-cli3.x开发环境中(router采用 history模式)出现Failed to resolve async component default: Error: Loading chu ...

  9. linux定时跑php脚本,防止重复跑,死循环

    $PHP_SELF = realpath($_SERVER['PHP_SELF']); if (!($argc > 1)) { $lock_file = $PHP_SELF . '.lock'; ...

  10. CesiumLab V1.4 分类3dtiles生成(倾斜单体化、楼层房间交互)我记得我是写过一篇关于倾斜单体化的简书文章的,但是现在找不到了。不过找不到也好,就让他随风逝去吧,因为当时我写那篇文章的时候,就发现了cesium实际是有另一种更高效的单体化。就下面这个示例https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/index.html?src=

    我记得我是写过一篇关于倾斜单体化的简书文章的,但是现在找不到了.不过找不到也好,就让他随风逝去吧,因为当时我写那篇文章的时候,就发现了cesium实际是有另一种更高效的单体化.就下面这个示例 http ...