这一章的内容涉及到更深层次的迭代器以及标准库的一些常见的算法
1.什么是泛型算法
简单来说,标准容器定义了很少的操作,无非是添加,删除元素;查找访问元素;获取元素指针等。因此,有必要获取更多的对于一些容器库的操作手段,但是我们又不想为每个容器库都写这些操作的成员函数,况且也没有这个必要。于是我们想到了是不是可以抽象出具体的算法,不关乎容器类型 的成员函数?很显然,这个想法就是泛型算法。官方定义:它们可以操作在不同的容器中,实现了相同的效用,独立于容器和类型,经常和迭代器捆绑在一起。
2.初窥算法
#include<algorithm>
#include<numeric>
(1)典型的只读算法
find ,accumulate,find_first_of;
find(iter,iter+6,search_value) //返回查找元素的迭代器
accumulate(vce.begin(),vce.end(),init_val) //vce元素之和再加上init_val
find_first_of
// find_first_of example
#include <iostream> // std::cout
#include <algorithm> // std::find_first_of
#include <vector> // std::vector
#include <cctype> // std::tolower
bool comp_case_insensitive (char c1, char c2) {
return (std::tolower(c1)==std::tolower(c2));
}
int main () {
int mychars[] = {'a','b','c','A','B','C'};
std::vector<char> haystack (mychars,mychars+6);
std::vector<char>::iterator it;
int needle[] = {'A','B','C'};
// using default comparison:
it = find_first_of (haystack.begin(), haystack.end(), needle, needle+3);
if (it!=haystack.end())
std::cout << "The first match is: " << *it << '\n';
// using predicate comparison:
it = find_first_of (haystack.begin(), haystack.end(),
needle, needle+3, comp_case_insensitive);
if (it!=haystack.end())
std::cout << "The first match is: " << *it << '\n';
return 0;
}
现在应该明白了这个函数的意思了。
(2)典型的写容器元素算法
fill
template <class ForwardIterator, class T>
void fill (ForwardIterator first, ForwardIterator last, const T& val)
{
while (first != last) {
*first = val;
++first;
}
}
// fill algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::fill
#include <vector> // std::vector
int main () {
std::vector<int> myvector (8); // myvector: 0 0 0 0 0 0 0 0
std::fill (myvector.begin(),myvector.begin()+4,5); // myvector: 5 5 5 5 0 0 0 0
std::fill (myvector.begin()+3,myvector.end()-2,8); // myvector: 5 5 5 8 8 8 0 0
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
output:myvector contains: 5 5 5 8 8 8 0 0
fill_n
template <class OutputIterator, class Size, class T>
OutputIterator fill_n (OutputIterator first, Size n, const T& val)
{
while (n>0) {
*first = val;
++first; --n;
}
return first; // since C++11
}
return value:An iterator pointing to the element that follows the last element filled
// fill_n example
#include <iostream> // std::cout
#include <algorithm> // std::fill_n
#include <vector> // std::vector
int main () {
std::vector<int> myvector (8,10); // myvector: 10 10 10 10 10 10 10 10
std::fill_n (myvector.begin(),4,20); // myvector: 20 20 20 20 10 10 10 10
std::fill_n (myvector.begin()+3,3,33); // myvector: 20 20 20 33 33 33 10 10
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
output:myvector contains: 20 20 20 33 33 33 10 10
back_inserter
// back_inserter example
#include <iostream> // std::cout
#include <iterator> // std::back_inserter
#include <vector> // std::vector
#include <algorithm> // std::copy
int main () {
std::vector<int> foo,bar;
for (int i=1; i<=5; i++)
{ foo.push_back(i); bar.push_back(i*10); }
std::copy (bar.begin(),bar.end(),back_inserter(foo));
std::cout << "foo contains:";
for ( std::vector<int>::iterator it = foo.begin(); it!= foo.end(); ++it )
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
copy
template<class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
while (first!=last) {
*result = *first;
++result; ++first;
}
return result;
}
// copy algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::copy
#include <vector> // std::vector
int main () {
int myints[]={10,20,30,40,50,60,70};
std::vector<int> myvector (7);
std::copy ( myints, myints+7, myvector.begin() );
std::cout << "myvector contains:";
for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}