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. json反序列化快捷实体类

    有时候我们反序列化一个json串只为了提取里面的数据,而且json串的层级结构可能会比较复杂,定义对应的实体类会多而杂,有时还不一定能达到想要的效果. 则可以关注下以下两个类: java :      ...

  2. linux及安全《Linux内核设计与实现》第二章——20135227黄晓妍

    第二章:从内核出发 2.1获取源代码 2.1.1使用git Git:内核开发者们用来管理Linux内核源代码的控制系统. 我们使用git来下载和管理Linux源代码. 2.1.2安装内核源代码(如果使 ...

  3. c++标准库vector&list使用练习

    /* vector顺序存储,随机访问快 list链表存储,插入删除快 deque占用内存多,兼具两者优点 注意: 1.vector严格顺序存储 2.list的迭代器只能做++或--运算,要一次移动多个 ...

  4. 2017-2018-1 JaWorld 团队作业--冲刺7

    2017-2018-1 JaWorld 团队作业--冲刺7 冲刺博客 冲刺1 冲刺2 冲刺3 冲刺4 冲刺5 项目完成情况 存在的问题 存在的问题是敌机只设置了一种,没能实现多种敌机的游戏设置. 界面 ...

  5. Python3基础 try-except 几个异常采取同样的处理方法

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

  6. IDEA使用Git管理项目

    今天将项目使用Git管理了,IDEA. 第一步: 第二步:

  7. SDN前瞻 网络的前世今生

    本文基于SDN导论的视频而成:SDN导论 目前网络层面流行的技术概念:虚拟中心:公有云私有云:数据中心等等. SDN主要的模拟器:Mininet OpenDaylight(Cisco) ONOS(AT ...

  8. python 三维数组找最小值

    #声明三维数组 num=[[[,,],[,,],[,,]], \ [[,,],[,,],[,,]]] value=num[][][]#设置main为num数组的第一个元素 ): ): ): if(va ...

  9. rxjava rxandroid使用遇到的坑

    今天在解决一个界面加载本地数据库数据的时候,使用rxjava在指定io线程操作是遇到一个问题,即使指定了在io线程操作,可是界面还是卡顿,最后通过打印线程Thread.currentThread(). ...

  10. poj3734矩阵快速幂

    挑战上面的题目,感觉脑洞很大 分别找红蓝个数全为偶,全为奇,一奇一偶的个数ai,bi,ci 转移矩阵是| 2 1 0 |,是一个对称矩阵(会不会有什么联系.) | 2 2 2 | | 0 1 2 | ...