STL 源代码剖析 算法 stl_algo.h -- rotate
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
rotate
--------------------------------------------------------------
描写叙述:将[first, middle) 内的元素和[middle, last) 内的元素互换。
/*------------------------------------------------------------
*分派函数(dispatch function)
*/
template <class ForwardIterator>
inline void rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last){
if(first == middle || middle == last) return ;
__rotate(first, middle, last, distance_type(first), iterator_category(first));
}
以下依据不同的迭代器类型完毕三个旋转操作
rotate 的 forward iterator 版
思路:
1.以短段为根据。相应元素逐一对调
2.调整,对新的前、后段再作交换
3.当两段都结束时,循环结束
复杂度:O(n)
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; ++i; // 双双前进 1
// 下面推断是前段[first, middle)先结束还是后段 [middle, last) 后结束
if(first == middle){ //前段结束了
if(i == last) return; //假设后段同一时候也结束,整个就结束了
middle = i;
}
else if(i == last){ //后段先结束
i = middle; // 调整。准备对新的的前、后段再作交换
}
}
}
rotate 的 bidirectional iterator 版
思路:
1.对前段逆转
2.对后段逆转
3.对总体逆转
复杂度:O(n)
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhlbmdzZW5saWU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
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);
}
rotate 的 random access iterator 版 --> ?? 看不太懂。。。
template<class RandomAccessIterator, class Distance>
void __rotate(RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last, Distance *,
random_access_iterator_tag){
//取全长和前段长度的最大公因子
Distance n = __gcd(last - first, middle - first);
while(n--){
__rotate_cycle(first, last, first + n, middle - first, value_type(first));
}
} template <class EuclideanRingElement>
EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n)
{
while (n != 0) {
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;
if (last - ptr2 > shift)
ptr2 += shift;
else
ptr2 = first + (shift - (last - ptr2));
}
*ptr1 = value;
}
演示样例:
char alpha[] = "abcdefghijklmnopqrstuvwxyz";
rotate(alpha, alpha + 13, alpha + 26);
printf("%s\n", alpha);
// The output is nopqrstuvwxyzabcdefghijklm
STL 源代码剖析 算法 stl_algo.h -- rotate的更多相关文章
- STL 源代码剖析 算法 stl_algo.h -- search
		
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search --------------------------------------- ...
 - STL 源代码剖析 算法 stl_algo.h -- partial_sort / partial_sort_copy
		
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie partial_sort / partial_sort_copy ------------- ...
 - STL 源代码剖析 算法 stl_algo.h -- lower_bound
		
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie lower_bound(应用于有序区间) ------------------------- ...
 - STL 源代码剖析 算法 stl_algo.h -- random_shuffle
		
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie random_shuffle ------------------------------- ...
 - STL 源代码剖析 算法 stl_algo.h -- merge sort
		
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie merge sort ----------------------------------- ...
 - STL 源代码剖析 算法 stl_algo.h -- partition
		
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie partition ------------------------------------ ...
 - STL 源代码剖析 算法 stl_algo.h -- equal_range
		
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie equal_range(应用于有序区间) ------------------------- ...
 - STL 源代码剖析 算法 stl_algo.h -- inplace_merge
		
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie inplace_merge(应用于有序区间) ----------------------- ...
 - STL 源代码剖析 算法 stl_algo.h -- next_permutation
		
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie next_permutation ----------------------------- ...
 
随机推荐
- Scala高手实战****第20课:Scala提取器、注解深度实战详解及Spark源码鉴赏
			
Spark中的源码的提取器和注解 @SparkContext.scala @ volatile 线程专用 保证线程间共享内容的一致性 @volatile private var _dagSchedul ...
 - java工具类获取properties文件的配置
			
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...
 - 调试Ajax调用的利器firebug
			
这几天我在家里调试PCS的Ajax调用时候发现一个问题就是调试手段太少,一般我会在进入ajax调用前加上一段alert输出变量信息. 比如 alert($("#taskid").v ...
 - dependency:copy-dependencies使用,如何排除应用自身module
			
相信用法参考:https://maven.apache.org/plugins/maven-dependency-plugin/copy-dependencies-mojo.html#includeG ...
 - gulp的入门浅析
			
阅读目录 介绍gulp 安装gulp gulpfile.js 运行gulp 介绍gulp的api 介绍gulp gulp是基于Nodejs的自动任务运行器, 她能自动化地完成 javascript/c ...
 - MySQL对时间的处理总结
			
1.to_days函数查询今天的数据:select * from 表名 where to_days(时间字段名) = to_days(now()); to_days函数:返回从0000年(公元1年)至 ...
 - ubuntu中wifi显示被硬件禁用的解决方法
			
本人使用的电脑是华硕X550C,安装了ubuntu16.04版本. 联网的时候显示“wifi已经通过硬件开关禁用”.按Fn+F2无法开启wifi.通过rfkill命令无法也无法开启wifi. 经过了解 ...
 - Spark createDirectStream 维护 Kafka offset(Scala)
			
createDirectStream方式需要自己维护offset,使程序可以实现中断后从中断处继续消费数据. KafkaManager.scala import kafka.common.TopicA ...
 - Java ArrayList的模拟实现
			
package test; import java.util.Arrays; import java.util.Collection; public class MyArrayList<E> ...
 - js 上传图片进行回显
			
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...