reverse

template <class BidirectionalIterator>
void reverse(BidirectionalIterator first,BidirectionalIterator last)//翻转range内iterator所指的元素而非iterator本身。

reverse_copy

  与reverse类似,只不过这个是把反转结果输出到result中,返回新产生的尾端,等同于先copy再reverse,[first,last)和[result,result+(last-first)不重叠

template <class BidirectionalIterator,class OutputIterator>
OutputIterator reverse_copy(BidirectionalIterator first,BidirectionalIterator last,OutputIterator result)

roate

  将range内的元素旋转,将middle处的元素旋转到first处,将middle+1处的元素旋转到first+1处,对于0<=n<=last-first区间内的每一个n,将元素*(first+n)赋值给*(first+(n+(last-middle))%(last-first)),也就是将[first,middle)与[middle,last)中的每个元素互换,可以用swap_ranges互换两个长度相同的range,用rotate换两个长度不同的相邻的range

inline void rotate(ForwardIterator first,ForwardIterator middle,ForwardIterator last)
{
if(first==middle||middle==last)
return ;
__roate(first,middle,last,distance_type(first),iterator_categroy(first));
}

ForwardIterator版本

template <class ForwardIterator, class Distance>
void __rotate(ForwardIterator first, ForwardIterator middle,
ForwardIterator last, Distance*, forward_iterator_tag) {
for (ForwardIterator i = middle;;) {
iter_swap(first, i); // 前后段元素一一交换
++first; // 双双前进1
++i;
// 以下判断是前段[first, middle)先结束还是后段[middle,last)先结束
if (first == middle) { // 前段先结束
if (i == last) return; // 如果后段也结束了,整个就结束了
middle = i; // 否则进行调整,之后再进行迭代
}
else if (i == last) // 后段先结束
i = middle; // 调整,之后再进行迭代
}
}

Bidirectionalterator版本

// 分派函数(dispatch function)
template <class BidirectionalIterator>
inline void reverse(BidirectionalIterator first, BidirectionalIterator last) {
__reverse(first, last, iterator_category(first));
}
// reverse 的 bidirectional iterator 版
template <class BidirectionalIterator>
void __reverse(BidirectionalIterator first, BidirectionalIterator last,
bidirectional_iterator_tag) {
while (true)
if (first == last || first == --last) //剩余需交换元素个数小于2
return;
else
iter_swap(first++, last); //iter_swap()函数为交换迭代器所指元素的值
}
// rotate 的 bidirectional iterator 版
template <class BidirectionalIterator, class Distance>
void __rotate(BidirectionalIterator first, BidirectionalIterator middle,
BidirectionalIterator last, Distance*,
bidirectional_iterator_tag) {
reverse(first, middle);
reverse(middle, last);
reverse(first, last);
}

RandomIterator版本

  每一次__rotate_cycle只能将t/n的元素正确的左移,其中t为容器内元素个数,n为last-first和middle-first的最大公约数,而这些被移动的元素是以n为等间距的,所以循环n次,并分别以串的前n个元素为起点进行__rotate_cycle操作,就能保证将所有的元素都移动到正确的位置上。

// 最大公因数,利用辗转相除法
// __gcd() 应用于 __rotate() 的 random access iterator 版
template <class EuclideanRingElement>
EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n)
{
while (n != ) {
EuclideanRingElement t = m % n;
m = n;
n = t;
}
return m;
}
template <class RandomAccessIterator, class Distance, class T>
void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last,
RandomAccessIterator initial, Distance shift, T*) {
T value = *initial; //记下链首元素的值,接下来链首元素“出列”留下一个“槽”
RandomAccessIterator ptr1 = initial;
RandomAccessIterator ptr2 = ptr1 + shift;//指向链中下一元素
while (ptr2 != initial) {
*ptr1 = *ptr2;
ptr1 = ptr2; //ptr1指向“槽”的位置
if (last - ptr2 > shift) //还没有到达最后一个元素
ptr2 += shift;
else
ptr2 = first + (shift - (last - ptr2));
}
*ptr1 = value;
}
// rotate 的 random access iterator 版
template <class RandomAccessIterator, class Distance>
void __rotate(RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last, Distance*,
random_access_iterator_tag) {
// 以下迭代器的相减操作只适用于RandomAccessIterator
// 取全长和前段长度的最大公因数
Distance n = __gcd(last - first, middle - first);
// 链数为gcd(m,n) 。链中元素个数为n/gcd(m,n)。
while (n--) //为了书写方便,先从最后一条链开始循环
__rotate_cycle(first, last, first + n, middle - first,
value_type(first));
}

rotate_copy

  与rotate类似,但是他不会就地的旋转range,而是把旋转后的range输出到一result开头的range中,返回新产生的range的尾端

template <class ForwardIterator,class OutputIterator>
inline void rotate_copy(ForwardIterator first,ForwardIterator middle,ForwardIterator last,OutputIterator result);

next_permutation

  从尾端开始向前寻找两相邻元素,第一元素为i,第二元素为ii,而且*i<*ii,找到这样一组元素后,再从尾端开始向前检验,找出第一大于*i的元素令其为*j,将i和j对调,再将ii之后的所有元素颠倒即为所求。

tmplate <class BidirectionIterator>
bool next_permutation(BidirectionIterator first, BidirectionIterator last)
{
if(first == last)
return false;
BidirectionIterator i = first;
++i;
if(i == last)
return false;
i = last;
--i; for(;;)
{
BidirectionIterator ii = i;
--i;
if(*i < *ii)
{
BidirectionIterator j = last;
while(!(*i < *--j));
  iter_swap(i, j);
reverse(ii, last);
return true;
}
if(i == first) {
reverse(first, last);
return false;
}
}
}
//版本二:用自定义的function object
template <class BidirectionalIterator,class StrictweakOrdering>
bool next_permutation(BidirectionalIterator first,BidirectionalIterator last,StrictweakOrdering cmo);

prev_permutation

  从尾端开始向前寻找两相邻元素,第一元素为i,第二元素为ii,而且*i>*ii,找到这样一组元素后,再从尾端开始向前检验,找出第一小于*i的元素令其为*j,将i和j对调,再将ii之后的所有元素颠倒即为所求。

//版本一:operator<
template <class BidirectionalIterator>
bool prev_permutation(BidirectionalIterator first,BidirectionalIterator last)
{
if(first == last)
return false;
BidirectionIterator i = first;
++i;
if(i == last)
return false;
i = last;
--i; for(;;) {
BidirectionIterator ii = i;
--i; if(*ii < *i) {
BidirectionIterator j = last;
while(!(*--j < *i));
iter_swap(i, j);
reverse(ii, last);
return true;
} if(i == first) {
reverse(first, last);
return false;
}
}
}
//版本二:用自定义的function object
template <class BidirectionalIterator,class StrictweakOrdering>
bool prev_permutation(BidirectionalIterator first,BidirectionalIterator last,StrictweakOrdering cmo);

排列算法(reverse...rotate...next_permutation)的更多相关文章

  1. 排列算法汇总(下一个排列,全排列,第K个排列)

    一.下一个排列 首先,STL提供了两个用来计算排列组合关系的算法,分别是next_permutation和prev_permutation. next_permutation(nums.begin() ...

  2. Java字符串排列算法

    Java字符串排列算法 题目:现有ABCDE 5个球 构成的排列组合 可重复抽取 最多取到16个 共有多少种组合方式? 比如:取1个球可以构成的组合有 A B C D E 共5种,取2个球可以构成的组 ...

  3. (转)排列算法 Permutation Generation

    转自:http://www.cnblogs.com/dragonpig/archive/2010/01/21/1653680.html http://www.notesandreviews.com/p ...

  4. LeetCode算法题-Rotate Array(Java实现)

    这是悦乐书的第184次更新,第186篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第43题(顺位题号是189).给定一个数组,将数组向右旋转k步,其中k为非负数.例如: ...

  5. STL 源代码剖析 算法 stl_algo.h -- next_permutation

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie next_permutation ----------------------------- ...

  6. 记一道有意思的算法题Rotate Image(旋转图像)

    题出自https://leetcode.com/problems/rotate-image/ 内容为: You are given an n x n 2D matrix representing an ...

  7. LeetCode算法题-Rotate String(Java实现)

    这是悦乐书的第317次更新,第338篇原创 在开始今天的算法题前,说几句,今天是世界读书日,推荐两本书给大家,<终身成长>和<禅与摩托车维修艺术>,值得好好阅读和反复阅读. 0 ...

  8. hdu1716排列2(stl:next_permutation+优先队列)

    排列2 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  9. 排列2(全排列next_permutation 注意格式)

    排列2 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

随机推荐

  1. Mac OS 终端下使用 Curl 命令下载文件

    在 mac os下,如何通过命令行来下载网络文件?如果你没有安装或 wget 命令,那么可以使用 curl 工具来达到我们的目的. curl命令参数: curl 'url地址' curl [选项] ' ...

  2. Linux及安全实践二

    Linux及安全实践二   基本内核模块 20135238 龚睿 1.  理解模块原理 linux模块是一些可以作为独立程序来编译的函数和数据类型的集合.之所以提供模块机制,是因为Linux本身是一个 ...

  3. Intellij IDEA 创建控制台项目,断点调试快捷方式

    在idea 2016中创建一个控制台项目(经常会忘) 打开创建界面 注意,什么都不要选,点击next(最坑的地方,经常忘) 再次点击next ============================= ...

  4. POJ - 3254 Corn Fields(状压DP)题解

    思路: 参照blog,用状压DP做,和题解稍微有点不一样,我这里直接储存了状态而不是索引. 这一题的问题是怎么判断相邻不能种,我们用2进制来表示每一行的种植情况.我们将每一行所能够造的所有可能都打表( ...

  5. 如何在官网下载JDK(版本、系统类型、字节位等)

    JDK官网地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 步骤1: 此步注意不要下载运行时jre

  6. Ubuntu 安装Docker

    参考:官网 安装依赖包: $ sudo apt-get update $ sudo apt-get install -y --no-install-recommends \ linux-image-e ...

  7. adb connect 192.168.1.10 failed to connect to 192.168.1.10:5555

    adb connect 192.168.1.10 输出 failed to connect to 关闭安卓端Wi-Fi,重新打开连接即可

  8. Phpstorm Alt+Enter 自动导入类

    很方便!!!能够自动提示哪些类没有自动加载!!!然后Alt+Enter进行安装!!!

  9. Yarn资源调度过程详细

    在MapReduce1.0中,我们都知道也存在和HDFS一样的单点故障问题,主要是JobTracker既负责资源管理,又负责任务分配. Yarn中可以添加多种计算框架,Hadoop,Spark,Map ...

  10. Java IO流-合并流

    2017-11-05 20:15:28 SequenceinputStream SequenceinputStream:SequenceInputStream 表示其他输入流的逻辑串联.它从输入流的有 ...