算法的标准样式:需要传进去两个指针
两个版本:
元素累加到 init 上
template <class InputIterator, class T>
T accumulate(InputIterator first, InputIterator last, T init)
{
for (; first != last; ++first)
init = init + *first; // 累加到init
return init;
}
元素累运算到 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); // 累运算到init上
return init;
}
这里可以用任意的二元操作(可以是函数,也可以是仿函数)
测试:
#include // std::cout
#include // std::minus
#include // std::accumulate
// 函数
int myfunc (int x, int y) {return x+2*y;}
// 仿函数
struct myclass {
int operator()(int x, int y) {return x+3*y;}
} myobj;
void test_accumulate()
{
cout << "\ntest_accumulate().......... \n";
int init = 100;
int nums[] = {10,20,30};
cout << "using default accumulate: ";
cout << accumulate(nums,nums+3,init); //160
cout << '\n';
cout << "using functional's minus: ";
cout << accumulate(nums, nums+3, init, minus<int>()); //40
cout << '\n';
cout << "using custom function: ";
cout << accumulate(nums, nums+3, init, myfunc); //220
cout << '\n';
cout << "using custom object: ";
cout << accumulate(nums, nums+3, init, myobj); //280
cout << '\n';
}
让范围里的所有元素都依次做同一件事情
Function 可以是函数也可以是仿函数
template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for (; first != last; ++first) {
f(*first);
}
return f;
}
与C++11中的 range-based for statement 差不多
replace
:范围内的所有等于 old_value 的,都被 new_value 取代
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
:范围内所有满足 pred()
为 true 的元素都被 new_value 取代
template <class ForwardIterator,class Predicate, class T>
void replace_if(ForwardIterator first, ForwardIterator last,
Predicate pred, const T& new_value)
{
for (; first != last; ++first)
{
if (pred(*first)) *first = new_value;
}
}
replace_copy
:范围内的元素全部 copy 到新地方,其中所有等于 old_value 的,都被替代为 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;
}
return result;
}
count
:在范围中计数值等于 value 的个数
template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type // 返回类型
count (InputIterator first, InputIterator last, const T& value)
{
typename iterator_traits<InputIterator>::difference_type n = 0;
for (; first != last; ++first)
{
if (*first == value) ++n;
}
return n;
}
count_if
:在范围中计数满足条件 pred()
的个数
template <class InputIterator, class Predicate>
typename iterator_traits<InputIterator>::difference_type // 返回类型
count_if (InputIterator first, InputIterator last, Predicate pred)
{
typename iterator_traits<InputIterator>::difference_type n = 0;
for (; first != last; ++first)
{
if (pred(*first)) ++n;
}
return n;
}
- 容器不带成员函数
count()
:array,vector,forward_list,deque- 容器自带成员函数
count()
:set / multiset,map / multimap,unordered_set / unordered_multiset,unordered_map / unorderd_multimap —— 所有关联式容器
find
:在范围内找到值等于 value 的元素
template <class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T& value)
{
while (first != last && *first != value) ++first;
return first;
}
find_if
:在范围内找到满足 pred()
的元素
template <class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last, Predicate pred)
{
while (first != last && !pred(*first)) ++first;
return first;
}
都是循序查找,效率低
- 容器不带成员函数
find()
:array,vector,forward_list,deque- 容器自带成员函数
find()
:set / multiset,map / multimap,unordered_set / unordered_multiset,unordered_map / unorderd_multimap —— 所有关联式容器
源码复杂
测试:
// 函数
bool myfunc (int i,int j) { return (i<j); }
//仿函数
struct myclass {
bool operator() (int i,int j) { return (i<j);}
} myobj;
// 定义向量
int myints[] = {32,71,12,45,26,80,53,33};
vector<int> myvec(myints, myints+8); // 32 71 12 45 26 80 53 33
// 用默认的比较(operator <)
sort(myvec.begin(), myvec.begin()+4); //(12 32 45 71)26 80 53 33
// 用自己的函数作比较
sort(myvec.begin()+4, myvec.end(), myfunc); // 12 32 45 71(26 33 53 80)
// 用自己的仿函数作比较
sort(myvec.begin(), myvec.end(), myobj); //(12 26 32 33 45 53 71 80)
// 用反向迭代器 reverse iterator 和默认的比较(operator <)
sort(myvec.rbegin(), myvec.rend()); // 80 71 53 45 33 32 26 12
// 用显式默认比较(operator <)
sort(myvec.begin(), myvec.end(), less<int>()); // 12 26 32 33 45 53 71 80
// 使用另一个比较标准(operator >)
sort(myvec.begin(), myvec.end(), greater<int>()); // 80 71 53 45 33 32 26 12
- 容器不带成员函数
sort()
:array,vector,deque,所有关联式容器(本身就排好序了)- 容器自带成员函数
sort()
:list,forward_list(只能用自带)
reverse iterator:
其中用的是 reverse_iterator —— iterator adapter
二分查找是否存在目标元素(并不给予位置),使用前必须先排序;其主要使用 lower_bound()
来找到能放入 val 的最低位置,再判断该元素是否存在
template <class ForwardIterator, class T>
bool binary_search(ForwardIterator first, ForwardIterator last, const T& value)
{
first = lower_bound(first, last, value);
return (first != last && !(value < *first));
// first == last 就是序列中所有元素都小于value
// first == last 时,*first是没有值的,所以需要先检查
// value < *first 就是序列中没有等于value的
}
lower_bound()
:用于在有序序列中查找==第一个大于等于==该值的元素(包括目标值本身),并返回一个指向该位置的迭代器
- 如果目标值在序列中多次出现,返回第一个出现的位置
- 如果目标值在序列中不存在,它将返回指向比目标值大的第一个元素位置,或者返回
last
upper_bound()
:用于在有序序列中查找==第一个大于==该值的元素(不包括目标值本身),并返回一个指向该位置的迭代器
- 如果目标值在序列中多次出现,返回第一个大于目标值的位置
- 如果目标值在序列中不存在,它将返回与
lower_bound()
一样的位置一样是前闭后开的原则,且他们都用的是二分查找的方法
仿函数专门为算法服务,设计成一个函数/仿函数是为了能传入算法
STL中的每个仿函数都继承了 binary_function
/ unary_function
—— 融入到STL中
STL规定每个 Adaptable Function(之后可以改造的函数)都应该继承其中一个(因为之后 Function Adapter 将会提问)
// 一个操作数的操作,例如“!”
template <class Arg, class Result>
struct unary_function
{
typedef Arg argument_type;
typedef Result result_type;
};
// 两个操作数的操作,例如“+”
template <class Arg1, class Arg2, class Result>
struct binary_function
{
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
// 理论大小都是0,实际上可能是1(如果有人继承,那就一定是0)
防函数是我们自己可能会写的,所以自己写的时候,如果想要融入STL,就要继承上面的两个之一