stl源码剖析 详细学习笔记 算法(1)
//---------------------------15/03/27----------------------------
//算法
{
/*
质变算法:会改变操作对象之值
所有的stl算法都作用在由迭代器[first,last)所标示出来的区间上。质变算法
就是
运算过程会更改区间内的元素内容
非质变算法:和质变算法相反
*/
/*
stl算法的一般形式
1>所有的泛型算法的前两个参数都是一对迭代器,通常称为first和last,用以标示算法的操作区间
2>stl习惯采用前闭后开区间,写成[first,last),表示区间包含first到last(不包含last)
之间的所有元素。
*/
//****************************数值算法*****************************
//accumulate
//把区间中的数都 “加到” init的副本中
最后返回init副本值
template<class InputIterator,
class T>
T accumulate(InputIterator first, InputIterator last, T init)
{
for(;first != last; ++first)
init = init + *first;
return init;
}
template<class InputIterator,class T,
class BinaryOperation>
T accumulate(InputIterator first, InputIterator last, T init,
BinaryOperation binary_op)
{
for(;first != last; ++first)
init = binary_op(init, *first);
return init;
}
//adjacent_difference
//把区间中的数都 “减去”
前一个数 并把结果输出到一个迭代器中
template<class InputIterator,
class OutputIterator>
OutputIterator adjacent_difference(InputIterator first, InputIterator last,
OutputIterator result)
{
if(first == last)
return result;
*result = *first;
return __adjacent_difference(first, last, result, value_type(first));
}
template<class InputIterator,
class OutputIterator,class T>
OutputIterator __adjacent_difference(InputIterator first, InputIterator last,
OutputIterator result, T*)
{
T value = *first;
while(++first != last)
{
T tmp = *first;
*++result = tmp - value;
value = tmp;
}
return ++result;
}
template<class InputIterator,
class OutputIterator,
class BinaryOperation>
OutputIterator adjacent_difference(InputIterator first, InputIterator last,
OutputIterator result,
BinaryOperation binary_op)
{
if(first == last)
return result;
*result = *first;
return __adjacent_difference(first, last, result, value_type(first),
binary_op);
}
template<class InputIterator,
class OutputIterator,class T>
OutputIterator __adjacent_difference(InputIterator first, InputIterator last,
OutputIterator result, T*,
BinaryOperation binary_op)
{
T value = *first;
while(++first != last)
{
T tmp = *first;
*++result = binary_op(tmp,value);
value = tmp;
}
return ++result;
}
//inner_product
//把两个区间中的数做 “内积”
并都 “加到” init的副本中并最后返回这副本
template<class InputIterator1,
class InputIterator2,class T>
T inner_product(InputIterator1 first1, InputIterator last1,
InputIterator2 first2, T init)
{
for(; first1 != last1; ++first1,++first2)
init = init + (*first1 * *first2);
return init;
}
template<class InputIterator1,
class InputIterator2,class T,
class BinaryOperation1,
class BinaryOperation2>
T inner_product(InputIterator1 first1, InputIterator last1,
InputIterator2 first2, T init, BinaryOperation1 binary_op1,
BinaryOperation2 binary_op2)
{
for(; first1 != last1; ++first1,++first2)
init = binary_op1(init, binary_op2(*first1, *first2));
return init;
}
//partial_sum
//把区间中的数都
累“加”
起来。 每加一次就输出一次到
指定迭代器。
template<class InputIterator,
class OutputIterator>
OutputIterator partial_sum(InputIterator first, InputIterator last,
OutputIterator result)
{
if(first == last)
return result;
*result = *first;
return __partial_sum(first, last, result, value_type(first));
}
template<class InputIterator,
class OutputIterator,class T>
OutputIterator __partial_sum(InputIterator first, InputIterator last,
OutputIterator result, T*)
{
T value = *first;
while(++first != last)
{
value = value + *first;
*++result = value;
}
return ++result;
}
template<class InputIterator,
class OutputIterator,
class BinaryOperation>
OutputIterator partial_sum(InputIterator first, InputIterator last,
OutputIterator result, BinaryOperation binary_op)
{
if(first == last)
return result;
*result = *first;
return __partial_sum(first, last, result, value_type(first), binary_op);
}
template<class InputIterator,
class OutputIterator,class T>
OutputIterator __partial_sum(InputIterator first, InputIterator last,
OutputIterator result, T*,
BinaryOperation binary_op)
{
T value = *first;
while(++first != last)
{
value = binary_op(value, *first);
*++result = value;
}
return ++result;
}
//power
template<class T,
class Interger>
inline T power(T x, Interger n)
{
return power(x,n,multiplies<T>());
}
template<class T,
class Interger, class MonoidOperation>
T power(T x, Interger n, MonoidOperation op)
{
)
return identity_element(op);
else
{
//确定 x的m次
值, 为了不重复计算,看n是否能被 x的m次
整除,通过移位便可确定
) ==
)
{
n >>=
;
x = op(x, x);
}
//也是为了不重复计算,把x的n次拆分成2^m+2^(m-1)+2^(m-2)+...+1
//先算出1次,再算出2次,再算出4次。只要对应位置上有数,加进reslt就行,
//没有数则不加。
T result = x;
n >>=
;
)
{
x = op(x, x);
) !=
)
result = op(result, x);
n >>=
;
}
return result;
}
}
// itoa
//在一个区间中依次写入value value+1...
template<class ForwardIterator,
class T>
void itoa(ForwardIterator first, ForwardIterator last, T value)
{
while(first != last)
*first++ = value++;
}
//****************************数值算法*****************************
//****************************基本算法*****************************
//equal
template<class InputIterator1,
class InputIterator2>
inline bool equal(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2)
{
for(; first != last1; ++first1,++first2)
if(*first1 != *first2)
return false;
return true;
}
template<class InputIterator1,
class InputIterator2,
class BinaryPredicate>
inline bool equal(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, BinaryPredicate binary_op)
{
for(; first != last1; ++first1,++first2)
if(!binary_op(*first1,*first2))
return false;
return true;
}
//fill
template<class ForwardIterator,
class T>
void fill(ForwardIterator first, ForwardIterator last,
const T& value)
{
for(; first != last; ++first)
*first = value;
}
//fill_n
//这里少了比较 first不需要和last比较来确定中止条件
所以只需要一个output迭代器
template<class OutputIterator,
class Size, class T>
OutputIterator fill_n(OutputIterator first, Size n,
const T& value)
{
; --n, ++first)
*first = value;
return first;
}
//iter_swap
template<class ForwardIterator1,
class ForwardIterator2>
inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b)
{
__iter_swap(a, b, value_type(a));
}
template<class ForwardIterator1,
class ForwardIterator2,
class T>
inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*)
{
T tmp = *a;
*a = *b;
*b = tmp;
}
//lexicographical_compare
按字典比较
template<class InputIterator1,
class InputIterator2>
bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2)
{
for(; first1 != last1 && first2 != last2; ++first1, ++first2)
{
if(*first1 < *first2)
return true;
if(*first2 < *first1)
return false
}
return first1 == last1 && first2 != last2;
}
template<class InputIterator1,
class InputIterator2,
class Compare>
bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
Compare comp)
{
for(; first1 != last1 && first2 != last2; ++first1, ++first2)
{
if(comp(*first1, *first2))
return true;
if(comp(*first2, *first1))
return false
}
return first1 == last1 && first2 != last2;
}
inline
bool
lexicographical_compare(const
unsigned char* first1,
const unsigned
char* last1,
const unsigned
char* first2,
const unsigned
char* last2)
{
const size_t len1 = last1 - first1;
const size_t len2 = last2 - first2;
const int result = memcmp(first1, first2, min(len1, len2));
? result <
: len1 < len2;
}
//max两者比较返回大值
template<class T>
inline const T& max(const T& a,
const T& b)
{
return a < b ? b : a;
}
template<class T,
class Compare>
inline const T& max(const T& a,
const T& b, Compare comp)
{
return comp(a, b) ? b : a;
}
//min两者比较返回小值
template<class T>
inline const T& min(const T& a,
const T& b)
{
return b < a ? b : a;
}
template<class T,
class Compare>
inline const T& min(const T& a,
const T& b, Compare comp)
{
return comp(b,a) ? b : a;
}
//mismatch
找到第一个不匹配点
template<class InputIterator1,
class InputIterator2>
pair<InputIterator1, InputIterator2> mismatch(
InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2)
{
while (first != last1 && *first1 == *first2)
{
++first1;
++first2;
}
return pair<InputIterator1, InputIterator2>(first1, first2);
}
template<class InputIterator1,
class InputIterator2,
class BinaryPredicate>
pair<InputIterator1, InputIterator2> mismatch(
InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
BinaryPredicate binary_pred)
{
while (first1 != last1 && binary_pred(*first1, *first2))
{
++first1;
++first2;
}
return pair<InputIterator1, InputIterator2>(first1, first2);
}
//swap
template<class T>
inline void swap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}
//copy这个函数为了强化效率下了血本
//正常版本走这边
template<class InputIterator,
class OutputIterator>
inline OutputIterator copy(InputIterator first, InputIterator last,
OutputIterator result)
{
return __copy_dispatch<InputIterator,OutputIterator>()
(first, last, result);
}
//char* wchar_t*
走这边
inline char* copy(const
char* first, const
char* last, char* result)
{
memmove(result, first, last - first);
return result + (last - first);
}
inline
wchar_t* copy(const
wchar_t* first, const
wchar_t* last,
const wchar_t* result)
{
memmove(result, first,
sizeof(wchar_t) * (last - first));
return result + (last - first);
}
//准备一个仿函数,用来再次特化,用仿函数可以根据传入的InputIterator来特化
//正常版本走这边
template<class InputIterator,
char OutputIterator>
struct __copy_dispatch
{
OutputIterator
operator()(InputIterator first, InputIterator last,
OutputIterator result)
{
//传入一个迭代器标签,区分是否是随机迭代器
return __copy(first, last, result, iterator_category(first));
}
};
//指针走这边
template<class T>
struct __copy_dispatch<T*, T*>
{
T*
operator()(T* first, T* last, T* result)
{
//判断
是否
没有 assignment_operator重载操作
typedef typename __type_traits<T>::has_trivial_assignment_operator t;
return __copy_t(first, last, result, t());
}
};
//const指针走这边
template<class T>
struct __copy_dispatch<const T*, T*>
{
T*
operator()(const T* first,
const T* last, T* result)
{
typedef typename __type_traits<T>:: has_trivial_assignment_operator t;
return __copy_t(first, last, result, t());
}
};
//input是基类,不管forward
还是bidi迭代器都走这边
template<class InputIterator,
class OutputIterator>
inline OutputIterator __copy(InputIterator first, InputIterator last,
OutputIterator result, input_iterator_tag)
{
for(; first != last; ++result, ++first)
*result = *first;
return result;
}
//随机迭代器走这边
template<class RandomAccessIterator,
class OutputIterator>
inline OutputIterator
__copy(RandomAccessIterator first, RandomAccessIterator last,
OutputIterator result, random_access_iterator_tag)
{
return __copy_d(first, last, result, distance_type(first));
}
//直接算出区间大小,根据大小来循环
不需要判断迭代是否相等,可以有效提升速度
template<class RandomAccessIterator,
class OutputIterator,
class Distance>
inline OutputIterator
__copy_d(RandomAccessIterator first, RandomAccessIterator last,
OutputIterator result, Distance*)
{
; --n, ++result, ++first )
*result = *first;
return result;
}
//是
没有assignment_operator重载操作的话
就走这。直接复制内存
template<class T>
inline T* __copy_t(const T* first,
const T* last, T* result,
__true_type)
{
memmove(result, first,
sizeof(T) * (last - first));
return result + (last - first);
}
//不是
没有assignment_operator重载操作(也就是有重载)
走这边,调用随机迭代器的copy方法
template<class T>
inline T* __copy_t(const T* first,
const T* last, T* result,
__false_type)
{
return __copy_d(first, last, result, (ptrdiff_t*)
);
}
stl源码剖析 详细学习笔记 算法(1)的更多相关文章
- 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源码剖析 详细学习笔记 算法(3)
//---------------------------15/03/30---------------------------- //min_element template<class Fo ...
- 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 ...
随机推荐
- 64位的Sql Server使用OPENROWSET导入xlsx格式的excel数据的时候报错(转载)
In the old times while all the CPUs were 32bit, we were happily using JET OLEDB Provider reaching Ex ...
- Linux学习---linux下的彩蛋和各种有趣的命令
[原文]https://www.toutiao.com/i6596596897392099844/ screenfetch 一个显示系统信息和主题信息的命令 使用方法 输入screenfetch 效果 ...
- 56_实现类似spring的可配置的AOP框架
> config.properties 配置文件 key=类名 > BeanFactory Bean工厂,负责得到bean getBean("xxx") &g ...
- css清楚浮动
在各种浏览器中显示效果也有可能不相同,这样让清除浮动更难了,下面总结8种清除浮动的方法,测试已通过 ie chrome firefox opera,需要的朋友可以参考下 浮动会使当前标签产生向上浮的效 ...
- DeepWalk学习
DeepWalk Background 使用机器学习的算法解决问题需要有大量的信息,但是现实世界中的网络中的信息往往比较少,这就导致传统机器学习算法不能在网络中广泛使用. (Ps: 传统机器学习分类问 ...
- day2-作业及答案
作业:第一组: 1.接收用户输入一个年份,判断是否是闰年(判断闰年的方法是该年能被4整除并且不能被100整除,或者是可以被400整除) 2.接收用户输入一组整数,输入负数时结束输入,输出这组数字的和: ...
- shiro实战系列(十五)之Spring集成Shiro
Shiro 的 JavaBean 兼容性使得它非常适合通过 Spring XML 或其他基于 Spring 的配置机制.Shiro 应用程序需要一个具 有单例 SecurityManager 实例的应 ...
- PAT B1048 数字加密 (20 分)
本题要求实现一种数字加密方法.首先固定一个加密用正整数 A,对任一正整数 B,将其每 1 位数字与 A 的对应位置上的数字进行以下运算:对奇数位,对应位的数字相加后对 13 取余——这里用 J 代表 ...
- 将如下三组不同类型的数据利用DataInputStream和DataOutputStream写入文件,然后从文件中读出
三组数据如下: {19.99 , 9.99 , 15.99 , 3.99 , 4.99} {12 , 8 , 13 ,29 ,50} {"Java T-shirt" , " ...
- OC分类(类目/类别) 和 类扩展 - 全解析
OC分类(类目/类别) 和 类扩展 - 全解析 具体见: oschina -> MyDemo -> 011.FoundationLog-OC分类剖析 http://blog.csdn. ...