#include<algorithm> //泛型算法
#include<numeric> //generalized numeric algorithm
back_inserter(#include<iterator>)
确保算法有足够的元素存储输出数据的一种方法是使用插入迭代器。
back_inserter生成一个绑定在该容器上的插入迭代器,赋值运算将调用push_back在容器中添加一个具有指定值的元素。
vector<int> vec;
fill_n(back_inserter(vec),10,0);
写入到目标迭代器的算法
vector<int> ivec;
copy(ilst.begin(),ilst.end(),back_inserter(ivec));
这个效率比较低,一般采用下面
vector<int> ivec(ilst.begin(),ilst.end());
replace算法
replace(ilst.begin(),ilst.end(),0,42);
//将所有值为0的替换为42
vector<int> ivec;
replace_cppy(ilst.begin(),ilst.end(),back_inserter(ivec),0,42);
// ivec存储ilst的一份副本,而ilst内所有的0在ivec中都变成了42
对容器元素重新排序算法
sort(words.begin(),words.end());
vector<string>::iterator end_unique = unique(words.begin(),words.end());
words.erase(end.unique(),words.end());
unique函数实际上并没有删除任何元素,而是将无重复的元素复制到序列前端,从而覆盖相邻的重复元素。(这个怎么实现??)
unique返回迭代器指向超出无重复元素范围末端的下一个位置
谓词函数
bool isShorter(const string& s1, const string & s2)
{
return s1.size() < s2.size();
}
bool GT6(const string& s)
{
return s.size() >= 6;
}
GT6函数缺陷,不通用?
stable_sort(words.begin( ),words.end( ),isShorter);
//谓词函数必须接受两个实参,实参类型必须与元素类型相同
一个完整的统计单词字母个数不小于6的程序
int main()
{
vector<string> words;
string next_word;
while(cin>>next_word)
words.push_back(next_word);
sort(words.begin(),words.end());
vector<string>::iterator end_unique = unique(words.begin(),words.end());
words.erase(end_unique,words.end());
stable_sort(words.begin(),words.end(),isShorter);
vector<string>::size_type wc = count_if(words.begin(),words.end(),GT6);
}
三种类型的迭代器
(1)插入迭代器
插入器是一种迭代器适配器,带有一个容器参数,并生成一个迭代器??
front_inserter需要push_front,换句话说,只有容器提供push_front操作时,才能用front_inserter.
(2) iostream迭代器
istream_iterator<T> in(strm) 创建从输入流strm中读取T类型对象的istream_iterator对象 |
istream_iterator<T> in; istream_iterator对象的超出末端的迭代器? |
ostream_iterator<T> in(strm); 创建T类型的对象写到输出流strm的ostream_iterator对象 |
ostream_iterator<T> in(strm,delim) 写入过程中delim作为元素的分隔符,delim是以空字符结束的字符数组 |
仔细体会下面两个应用:
istream_iterator<int> cin_it(cin);
istream_iterator<int> end_of_stream;
ofstream outfile;
ostream_iterator<Sales_item> output(outfile," ");
ostream_iterator对象和ostream_iterator对象的使用
ostream_iterator<string> out_iter(cout,"\n");
istream_iterator<string> in_iter(cin),eof;
while(in_iter != eof)
*out_iter++ = *in_iter++;
与算法一起使用流迭代器
istream_iterator<int> cin_it(cin);
istream_iterator<int> end_of_stream;
vector<int> vec(cin_it,end_of_stream);
sort(vec.begin(),vec.end());
ostream_iterator<int> output(cout," ");
unique_copy(vec.begin(),vec.end(),output);
unique_copy算法将输入范围中不重复的值复制到目标迭代器,而目标迭代器已经和cout对象关联了。
(3)反向迭代器
vector<int> vec;
for(vector<int>::size_type i = 0; i != 10; ++i)
vec.push_back(i);
vector<int>::reverse_iterator r_iter;
for(r_iter = vec.rbegin(); r_iter != vec.rend(); ++r_iter)
cout<<*r_iter<<endl;
流迭代器不能反向遍历流,所以流迭代器不能创建反向迭代器。
输出列表中的最后一个单词
string::reverse_iterator rcomma = find(line.rbegin(),line.rend(),',');
cout<<string(line.rbegin(),rcomma);
如果输入是BOY,GIRL
输出时LRIG,正确的使用反向迭代器的base成员函数
cout<<string(rcomma.base(),line.end())<<endl;
[rcomma.base( ),line.end( ) )
使用普通的迭代器对反向迭代器进行初始化或赋值时,所得到的迭代器并不是指向原迭代器所指向的元素????
const迭代器
const_iterator: 不能改变迭代器指向的元素。
输入迭代器 读,不能写;只支持++运算 |
输出迭代器 写,不能读;只支持++运算 |
前向迭代器 读和写;只支持++运算 |
双向迭代器 读和写;支持++和--运算 |
随机访问迭代器 读和写;支持完整的迭代器算术运算 |
算法最基本的性质是需要使用的迭代器的种类。所有算法都指定了它的每个迭代器形参可使用的迭代器类型。
容器特有的算法和泛型算法区别