排列算法(reverse...rotate...next_permutation)
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)的更多相关文章
- 排列算法汇总(下一个排列,全排列,第K个排列)
一.下一个排列 首先,STL提供了两个用来计算排列组合关系的算法,分别是next_permutation和prev_permutation. next_permutation(nums.begin() ...
- Java字符串排列算法
Java字符串排列算法 题目:现有ABCDE 5个球 构成的排列组合 可重复抽取 最多取到16个 共有多少种组合方式? 比如:取1个球可以构成的组合有 A B C D E 共5种,取2个球可以构成的组 ...
- (转)排列算法 Permutation Generation
转自:http://www.cnblogs.com/dragonpig/archive/2010/01/21/1653680.html http://www.notesandreviews.com/p ...
- LeetCode算法题-Rotate Array(Java实现)
这是悦乐书的第184次更新,第186篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第43题(顺位题号是189).给定一个数组,将数组向右旋转k步,其中k为非负数.例如: ...
- STL 源代码剖析 算法 stl_algo.h -- next_permutation
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie next_permutation ----------------------------- ...
- 记一道有意思的算法题Rotate Image(旋转图像)
题出自https://leetcode.com/problems/rotate-image/ 内容为: You are given an n x n 2D matrix representing an ...
- LeetCode算法题-Rotate String(Java实现)
这是悦乐书的第317次更新,第338篇原创 在开始今天的算法题前,说几句,今天是世界读书日,推荐两本书给大家,<终身成长>和<禅与摩托车维修艺术>,值得好好阅读和反复阅读. 0 ...
- hdu1716排列2(stl:next_permutation+优先队列)
排列2 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- 排列2(全排列next_permutation 注意格式)
排列2 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
随机推荐
- 报错org.openqa.selenium.WebDriverException: disconnected: unable to connect to renderer解决方法
做自动化时经常会遇到不兼容的问题,比如以下简单的脚本,主要是打开浏览器,然后最大化窗口,打开百度,输入内容搜索,代码如下: package com.gs.selenium; import org.op ...
- Redis 资料整理
Redis is an open source, BSD licensed, advanced key-value store. Redis is often referred to as a dat ...
- 从知乎了解到,为什么Mysql禁用存储过程、外键和级联?
打开帖子直接一张醒目的图,是阿里巴巴的Java开发手册对Mysql相关的要求. 看看下面的回复 灵剑 存储过程没有版本控制,版本迭代的时候要更新很麻烦.存储过程如果和外部程序结合起来用,更新的时候很难 ...
- bzoj1613 / P1353 [USACO08JAN]跑步Running
P1353 [USACO08JAN]跑步Running 显然的dp 设$f[i][j]$表示进行到第$i$分钟时,$j$疲劳度下的最远距离,$d[i]$为第$i$分钟下能跑的距离 分类讨论 1.运动: ...
- 20145204 《Java程序设计》第四周学习总结
20145204 <Java程序设计>第四周学习总结 教材学习内容总结 继承 什么时候使用继承? 当多个类中出现重复定义的行为(即多个类中出现重复的代码)时,就把相同的程序代码提成为父类. ...
- c#解析Lrc歌词文件
看到很多人解析歌词文件时写了一大片的字符处理代码,而且看得不是很明白,所以自己研究了一下, 首先来了解下Lrc文件 时间格式: 1.标准格式: [分钟:秒.毫秒] 歌词 注释:括号.冒号.点号全都要求 ...
- (转载)YOLO配置文件理解
YOLO配置文件理解 转载自 [net] batch=64 每batch个样本更新一次参数. subdivisions=8 如果内存不够大,将batch分割为subdivisions个子batch,每 ...
- SpringBoot与Dubbo整合下篇
(1)pom.xml引入相关依赖jar包,如下: <dependency> <groupId>com.alibaba</groupId> <artifactI ...
- Codeforces Round #417 (Div. 2) D. Sagheer and Kindergarten(树中判祖先)
http://codeforces.com/contest/812/problem/D 题意: 现在有n个孩子,m个玩具,每次输入x y,表示x孩子想要y玩具,如果y玩具没人玩,那么x就可以去玩,如果 ...
- hdu 4417 Super Mario 树状数组||主席树
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Prob ...