泛型程序设计

#include<algorithm> //泛型算法 #include<numeric> //generalized numeric algorithm back_inserter(#include<iterator>) 确保算法有足够的元素存储输出数据的一种方法是使用插入迭代器 。

#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迭代器

  

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: 不能改变迭代器指向的元素。

迭代器种类
输入迭代器 读,不能写;只支持++运算
输出迭代器 写,不能读;只支持++运算
前向迭代器 读和写;只支持++运算
双向迭代器 读和写;支持++和--运算
随机访问迭代器 读和写;支持完整的迭代器算术运算


算法最基本的性质是需要使用的迭代器的种类。所有算法都指定了它的每个迭代器形参可使用的迭代器类型。


容器特有的算法和泛型算法区别


知秋君
上一篇 2024-08-24 16:48
下一篇 2024-08-24 16:12

相关推荐