stl源码剖析 详细学习笔记 算法(3)
//---------------------------15/03/30----------------------------
//min_element
template<class ForwardIterator>
ForwardIterator min_element(ForwardIterator first, ForwardIterator last)
{
if(first == last)
return first;
ForwardIterator result = first;
while(++first != last)
if(*first < *result)
//自定义版本if(comp(*first, *result))
result = first;
return result;
}
//partition
//快排的基本步骤:划分,让判断true的元素放在区间前,让判断为false的元素放在区间后
//返回第一个非true的位置:第一种情况 end。第二种情况
元素被判断为flase
//这是不稳定的。
template<class BidirectionalIterator,
class Predicate>
BidirectionalIterator partition(BidirectionalIterator first,
BidirectionalIterator last,
Predicate pred)
{
while (true)
{
while (true)
{
if(first == last)
return first;
else if(pred(*first))
++first;
else
break;
}
--last; //第一次指向的事end所以--
之后指向的是判断过的数,所以要--
while (true)
{
if(first == last)
return first;
else if(!pred(*last))
--last;
else
break;
}
iter_swap(first, last);
++first;
//接下来要判断下一个
}
}
//remove
template<class ForwardIterator,
class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last,
const T& value)
{
first = find(first, last, value);
ForwardIterator next = first;
return first == last ? first : remove_copy(++next, last, first, value);
}
template<class InputIterator,
class OutputIterator,
class T>
OutputIterator remove_copy(InputIterator, first, InputIterator last,
OutputIterator result,
const T& value)
{
for(; first != last; ++first)
if(*first != value)
//remove_copy_if版本 if(!pred(*first))
{
*result = *first;
++result;
}
return result;
}
//replace
template<class ForwardIterator,
class T>
void replace(ForwardIterator first, ForwardIterator last,
const T& old_value,
const T& new_value)
{
for(; first != last; ++first)
if(*first == old_value)
*first = new_value;
//replace_if版本 if(pred(*first)) *first = new_value;
}
template<class InputIterator,
class OutputIterator,
class T>
OutputIterator replace_copy(InputIterator first, InputIterator last,
OutputIterator result,
const T& old_value,
const T& new_value)
{
for(; first != last; ++first, ++result)
*result = *first == old_value ? new_value : *first;
//replace_copy_if版本 *result = pred(*first) ? new_value : *first;
return result;
}
//reverse
template<class BidirectionalIterator>
inline void reverse(BidirectionalIterator first, BidirectionalIterator last)
{
__reverse(first, last, iterator_category(first));
}
template<class BidirectionalIterator>
void __reverse(BidirectionalIterator first, BidirectionalIterator last,
bidirectional_iterator_tag)
{
while (true)
{
if(first == last || first == --last)
return;
else
iter_swap(first++, last);
}
}
//随机迭代器的版本只需要判断一次
而非随机迭代器要判断两次,故效率上有差距,所以分开写
template<class RandomAccessIterator>
void __reverse(RandomAccessIterator first, RandomAccessIterator last,
random_access_iterator_tag)
{
while(first < last)
iter_swap(first++, --last);
}
template<class BidirectionalIterator,
class OutputIterator>
OutputIterator reverse_copy(BidirectionalIterator first,
BidirectionalIterator last,
OutputIterator result)
{
while (first != last)
{
--last;
*result = *last;
++result;
}
return result;
}
//rotate
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));
}
//单向的迭代器走这边
//只能单向行走,效率最低,要赋值起码1.5n次(当两者区间相同时)。
//调用一次swap就要赋值3次
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;
if(first == middle)
{
if(i == last)
return;
middle = i;
}
else if(i ==last)
i = middle;
}
}
//三次反转
固定赋值1.5n次
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);
}
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)
{
)
{
EuclideanRingElement t = m % n;
m = n;
n = t;
}
return m;
}
//最差的情况赋值1.5n次(当区间相等时),最少赋值n+1次(第一个或第二个区间为1时)。
template<class RandomAccessIteratorm,
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;
}
//rotate_copy
template<class ForwardIterator,
class OutputIterator>
OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle,
ForwardIterator last, OutputIterator result)
{
return copy(first, middle, copy(middle, last, result));
}
//search
template<class ForwardIterator1,
class ForwardIterator2>
inline ForwardIterator search(ForwardIterator1 first1,
ForwardIterator1 last1,
ForwardIterator2 first2,
ForwardIterator last2)
{
return __search(first1, last1, first2, last2,distance_type(first1),
distance_type(first2));
}
template<class ForwardIterator1,
class ForwardIterator2,
class distance1,
class Distance2>
ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
Distance1*, Distance2*)
{
Distance1 d1 =
;
distance(first1, last1, d1);
Distance2 d2 =
;
distance(first2, last2, d2);
if(d1 < d2) return last1;
ForwardIterator1 current1 = first1;
ForwardIterator2 current2 = first2;
while (current2 != last2)
{
if (*current1 == *current2)
{
++current1;
++current2;
}
else
{
if (d1 == d2)
return last1;
else
{
current1 = ++first1;
current2 = first2;
--d1;
}
}
}
return first1;
}
//search_n
template<class ForwardIterator,
class Interger, class T>
ForwardIterator search_n(ForwardIterator first,
ForwardIterator last,
Interger count,
const T& value)
{
)
return first;
else
{
//先找到第一个
first = find(first, last, value);
while (first != last)
{
Interger n = count -
;
ForwardIterator i = first;
++i;
//找连续符合的元素,都找到了的话 n会等于0;
&& *i == value)
{
++i;
--n;
}
)
return first;
else
first = find(i, last, value);
}
return last;
}
}
template<class ForwardIterator,
class Interger, class T,
class BinaryPredicate>
ForwardIterator search_n(ForwardIterator first,
ForwardIterator last,
Interger count,
const T& value,
BinaryPredicate binary_pred)
{
)
return first;
else
{
//自己实现find,其实可以使用find_if版本的
不过需要使用bind函数
while (first != last)
{
if(binary_pred(*first, value))
break;
++first;
}
while (first != last)
{
Interger n = count -
;
ForwardIterator i = first;
++i;
//找连续符合的元素,都找到了的话 n会等于0;
&& *i == value)
{
++i;
--n;
}
)
return first;
else
{
while (i != last)
{
if(binary_pred(*first, value))
break;
++i;
}
first = i;
}
}
return last;
}
}
//swap_ranges
//区间不能重叠,不然会产生未知结果
template<class ForwardIterator1,
class ForwardIterator2>
ForwardIterator2 swap_ranges(ForwardIterator1 first1,
ForwardIterator1 last1,
ForwardIterator2 first2)
{
for(; first != last1; ++first1, ++first2)
iter_swap(first1, first2);
return first2;
}
//transform
//对每个元素执行op操作后,复制到目的区间
template<class InputIterator,
class OutputIterator,
class UnaryOperation>
OutputIterator transform(InputIterator first1, InputIterator last,
OutputIterator result, UnaryOperation op)
{
for(; first != last; ++first, ++result)
*result = op(*first);
return result;
}
template<class InputIterator1,
class InputIterator2,
class OutputIterator,
class BinaryOperation>
OutputIterator transform(InputIterator1 first1, InputIterator last1,
InputIterator2 first2, InputIterator last2,
BinaryOperation binary_op)
{
for(; first1 != last1; ++first1, ++first2, ++result)
*result = binary_op(*first1, *first2);
return result;
}
//unique
//只能移除相邻的重复元素(首先要有相邻元素才会开始删除,相邻元素后面如果还有同样的元素也会被删除)
//要移除所有重复元素必须先排序
template<class ForwardIterator>
ForwardIterator unique(ForwardIterator first, ForwardIterator last)
{
first = adjacent_find(first, last);
return unique_copy(first, last, first);
}
template<class InputIterator,
class ForwardIterator>
inline OutputIterator unique_copy(InputIterator first,
InputIterator last,
OutputIterator result)
{
if(first == last)
return result;
return __unique_copy(first, last, result, iterator_category(result));
}
template<class InputIterator,
class ForwardIterator>
ForwardIterator __unique_copy(InputIterator first,
InputIterator last,
ForwardIterator result,
forward_iterator_tag)
{
*result = *first;
while (++first != last)
{
if(*result != *first)
*++result = *first;
}
return ++result;
}
template<class InputIterator,
class OutputIterator>
inline OutputIterator __unique_copy(InputIterator first,
InputIterator last,
ForwardIterator result,
output_iterator_tag)
{
return __unique_copy(first, last, result, value_type(first));
}
template<class InputIterator,
class OutputIterator,
class T>
OutputIterator __unique_copy(InputIterator first, InputIterator last,
OutputIterator result, T*)
{
T value = *first;
*result = value;
while (++first != last)
{
if(value != *first)
//如果result为只读,这里就只能通过值判断
而不能使用(*result != *first)
{
value = *first;
*++result = value;
}
}
return ++result;
}
stl源码剖析 详细学习笔记 算法(3)的更多相关文章
- stl源码剖析 详细学习笔记 算法(1)
//---------------------------15/03/27---------------------------- //算法 { /* 质变算法:会改变操作对象之值 所有的stl算法都 ...
- stl源码剖析 详细学习笔记 算法总览
//****************************基本算法***************************** /* stl算法总览,不在stl标准规格的sgi专属算法,都以 *加以标 ...
- stl源码剖析 详细学习笔记 算法(2)
//---------------------------15/03/29---------------------------- //****************************set相 ...
- stl源码剖析 详细学习笔记 算法(5)
//---------------------------15/04/01---------------------------- //inplace_merge(要求有序) template< ...
- stl源码剖析 详细学习笔记 算法(4)
//---------------------------15/03/31---------------------------- //lower_bound(要求有序) template<cl ...
- stl源码剖析 详细学习笔记 hashtable
//---------------------------15/03/24---------------------------- //hashtable { /* 概述: sgi采用的是开链法完成h ...
- stl源码剖析 详细学习笔记 set map
// // set map.cpp // 笔记 // // Created by fam on 15/3/23. // // //---------------------------15/03 ...
- stl源码剖析 详细学习笔记 RB_tree (2)
//---------------------------15/03/22---------------------------- //一直好奇KeyOfValue是什么,查了下就是一个和仿函数差不多 ...
- stl源码剖析 详细学习笔记 RB_tree (1)
// // RB_tree_STL.cpp // 笔记 // // Created by fam on 15/3/21. // // #include "RB_tree_STL.h&q ...
随机推荐
- CAC的Debian-8-64bit安装BBR正确方式是?
裝过三台debian 64 bit, CAC, 2歐, KVM虛擬機 做法都一樣 0. 有裝銳速記得先刪除, 免得換核心後, 銳速在扯後腿 1.換4.9版kernel 有正式版 別裝啥rc版, 4.9 ...
- 类Unix上5个最佳开源备份工具 Bacula/Amanda/Backupninja/Backuppc/UrBackup
当为一个企业选择备份工具的时候,你都考虑什么呢? 确定你正在部署的软件具有下面的特性 开源软件 – 你务必要选择那些源码可以免费获得,并且可以修改的软件.确信可以恢复你的数据,即使是软件供应商/项目停 ...
- Node.js环境搭建和学习(windwos环境)
Node.js环境搭建和学习 一.环境搭建 1.下载安装文件 下载地址http://nodejs-org.qiniudn.com/下载Node.js环境安装包,根据操作系统下载对应的安装包 下载地址 ...
- windows系统利用任务管理器-资源监视器了解程序的磁盘读写量
场景摘要: 1.刚部署上线一个新功能,增加了日志输出模块 2.本身服务器资源已经紧张了,在增加日志输出,就想了解磁盘读写量 3.从中突然发现oracle的磁盘读写量比较大 4.在展开明细发现是or ...
- opengl 实体和网格绘图函数(基础)(转)
http://blog.csdn.net/he_wen_jian/article/details/8594880 GLUT工具箱提供几种图形3维图形的函数: void glutWireSphere(G ...
- EXI6.0的安装(找不到网卡、找不到磁盘)
给一台华为2488 V5 服务器安装EXI6.0服务 (问过华为售后不支持EXI5.5的安装,建议EXI6.0及以上版本) 根据界面提示信息按“Del”.进入BIOS设置界面 参考博客地址:https ...
- BZOJ4892:[TJOI2017]dna(hash)
Description 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够表 ...
- java中Integer与int装箱拆箱一点收获
示例代码: class BoxIntInteger { public static void main(String[] args) { Integer a = new Integer(10111); ...
- Scala学习之路 (六)Scala的类、对象、继承、特质
一.类 1.类的定义 scala语言中没有static成员存在,但是scala允许以某种方式去使用static成员这个就是伴生机制,所谓伴生,就是在语言层面上,把static成员和非static成员用 ...
- 网站横幅切换jquery 插件
最近做一个web项目,站点首页需要像 百度统计 页面类似的切换横幅,有兴趣的可以先看看它的效果,这样就比较容易理解为什么我单独做个插件.其实类似的 jquery 插件网上类似的多的去了,随便网上下了两 ...