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. ArrayBuffer:类型化数组

    类型化数组是JavaScript操作二进制数据的一个接口. 这要从WebGL项目的诞生说起,所谓WebGL,就是指浏览器与显卡之间的通信接口,为了满足JavaScript与显卡之间大量的.实时的数据交 ...

  2. PHP开发之thinkPHP分层设计

    thinkphp模型层Model.Logic.Service讲解        ThinkPHP支持模型的分层 ,除了Model层之外,我们可以项目的需要设计和创建其他的模型层. 通常情况下,不同的分 ...

  3. Core Java 5

    p273~p276: 1.获取异常的更多信息:e.getMessage(). 2.得到异常的实际类型:e.getClass().getName(). 3.当异常之间不存在子类关系,并且异常的处理机制( ...

  4. Ubuntu18.04 怎么开热点

    先说明,电脑上要有wifi适配器,而且连接wifi时,不能开热点 我的笔记本是双系统,现在介绍一下我的设置 在设置里打开热点这个应该会吧,但是热点密码不是自己设置的,而是随机生成的,本文重点介绍一下怎 ...

  5. ubuntu 16.04下更换源和pip源【转】

    本文转载自:https://blog.csdn.net/weixin_41500849/article/details/80246221 写在前面的话 本文主要内容是更换系统源为清华大学源,更换pyt ...

  6. ThinkPHP开发博客系统笔记之一

    1.前后台搭建 开发的第一步是搭建前后台系统.搭建前台系统的时候新建了LoginController控制器和登录界面View/Login/index.tpl.模板文件中需要引入js和css文件,这里想 ...

  7. 介绍一个python视频处理库:moviepy

    由于博客园的插件和我自己博客的插件不一致,代码以及视频插入转换很麻烦,所以还是我原来博客的地址查看吧. 介绍一个python视频处理库:moviepy

  8. TC 配置插件

    转载:http://hi.baidu.com/accplaystation/item/07534686f39dc329100ef310 1.插件下载地址:http://www.topcoder.com ...

  9. vue项目打包部署到nginx 服务器上

    假如要实现的效果如下 http://ip/vue    =>是进入首页访问的路径是  usr/local/nginx/html/vue http://ip/website     =>是进 ...

  10. hive grouping sets 等聚合函数

    函数说明: grouping sets 在一个 group by 查询中,根据不同的维度组合进行聚合,等价于将不同维度的 group by 结果集进行 union allcube 根据 group b ...