C++ Primer(11)泛型算法

本文介绍了泛型算法的基本概念,包括算法如何通过迭代器而非容器进行操作的特点。此外,文中详细解释了如何使用find_first_of等算法进行元素查找及计数,并探讨了不同类型的迭代器,如插入迭代器、iostream迭代器和反向迭代器的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关键概念:算法永不执行容器提供的操作

泛型算法本身从不执行容器操作,只是单独依赖迭代器和迭代器操作实现。算法基于迭代器及其操作实现,而并非基于容器操作。使用迭代器时,算法从不修改基础容器的大小,也许会改变存储在容器中的元素的值,也许会在容器内移动元素,但是,算法从不直接添加或删除元素。

 

使用泛型算法必须包含algorithm头文件:

   #include <algorithm>

 

标准库还定义了一组泛化的算术算法,其命名习惯与泛型算法相同。使用这些算法则必须包含numeric头文件:

   #include <numeric>

 

eg:int sum = accumulate(vec.begin(),vec.end(),42);

     //sum the elements in vec starting the summation with the value 42

 

     string sum = accumulate(v.begin(),v.end(),string(""));

     //concatenate elements from v and store in sum

 

find_first_of的使用:

这个算法带有两对迭代器参数来标记两段元素范围,在第一段范围内查找与第二段范围中任意元素匹配的元素,然后返回一个迭代器,指向第一个匹配的元素。如果找不到匹配元素,则返回第一个范围的end迭代器。

假设roster1和roster2是两个存放名字的list对象,可使用find_first_of统计有多少个名字同时出现在这两个列表中:

size_it cnt = 0;

list<string>::iterator it = roster1.begin();

while ((it = find_first_of(it,roster1.end(),roster2.begin(),roster2.end())) != roster1.end())  {

         ++cnt;

         ++it;

       }

    cout << "Found" << cnt   << " names on both rosters "" << endl;

 

写入输入序列的元素:

eg:fill(vec.begin(),vec.end(),0);

     fill(vec.begin(),vec.begin()+vec.size()/2,10);

 

不检查写入操作的算法:

fill_n函数假定对指定数量的元素做写操作是安全的。

 

引入back_insert

确保算法有足够的元素存储输出数据的一种方法是使用插入迭代器(insert iterator)。

#include <iterator>

eg:vector<int> vec;  //empty vector

     fill_n(back_inserter(vec),10,0);   //appends 10 elements to vec

 

写入到目标迭代器的算法

eg: vector<int> ivec;

       copy (ilst.begin(),ilst.end(),back_inserter(ivec));//copy从输入范围中读取元素,然后将它们复制给目标ivec。

这个例子效率比较差,如果要以一个已存在的容器为副本创建新容器,更好的方法是直接用输入范围作为新构造容器的初始化:

vector<int> ivec(ilist.begin(),ilst.end());

 

算法的_copy版本

replace算法对输入序列做读写操作,将序列中特定的值替换为新的值:

  eg:replace(ilst.begn(),ilst.end(),0,42);//将所有值为0的实例替换成42。

如不想改变原来的序列,则调用replace_copy.

eg:vector<int> ivec;

      replace_copy (ilst.begin(),ilst.end(),back_inserter(ivec),0,42);

    调用该函数后,ilst没有改变,ivec存储ilst的一份副本,而ilst内所有的0在ivec中都变成了42.

 

对容器元素重新排序的算法

去除重复:

eg:sort(words.begin(),words.end());

      //删除相邻的重复元素,然后重新排列输入范围内的元素,并返回一个迭代器,表示无重复的值范围的结束。

      vector<string>::iterator end)unique = unique(words.begin(),words.end());

      //删除从end_unique指向的元素开始到words的最后一个元素也删掉为止。没有得复元素的vector对象,erase也是安全的。

      words.erase(end_unique,words.end());

 

再谈迭代器

    1、插入迭代器(insert iterator):与容器绑定在一起,实现在容器中插入元素的功能。

    2、iostream迭代器(iostream iterator):可与输入或输出流绑定在一起,用于迭代遍历所关联的IO流。

    3、反向迭代器(reverse iterator):实现向后遍历,耍花招不是向前遍历。所有容器类型都定义了自已的reverse_iterator类型,由rbegin和rend成员函数返回。

上述迭代器类型都在iterator头文件中定义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值