C++中的泛型算法

C++中标准库并未给容器添加大量功能,而是提供了一组算法,这些算法大多独立于任何特定的容器,这些算法可用于不同类型的容器和不同类型的元素,它们称为泛型算法。

1 初识泛型算法

1.1 只读算法
(1)find()算法

int val = 42
auto result = find(vec.cbegin(), vec.cend(), val);
cout << "The value" << val << (result == vec.cend() ? "is not present" : "is present") <<endl;

传递给find的前两个参数是表示元素范围的迭代器,第三个参数是一个值。find将范围中的每个元素与给定值进行比较。它将返回指向第一个等于给定值的元素的迭代器,如果范围中无匹配元素,则find返回第二个元素表示搜索失败,我们可以通过比较返回值和第二个参数来判断搜索是否成功。
(2)accumulate()算法

string sum = accumulate(v.cbegin(), v.cend(), string(""));

accumulate定义在numeric.h中,将第三个参数作为求和起点,前两个参数为需要求和的元素的范围。第三个参数必须定义了+运算符,故本例中第三个参数不能为一个空串"",因为""为const char*类型,没有+运算符。
(3)equal()算法
equal用于确定两个序列是否保存相同的值,它将第一个序列中的每个元素与第二个序列中的对应元素进行比较,如果所有对应元素都相等则返回true,否则返回false。

// roster2中的元素数目应该至少与roster1一样多
equal(roster1.cbegin(), roster1.cend(), roster2.cbegin())

equal利用迭代器完成操作,因此我们可以调用equal比较两个不同类型的容器中的元素,元素类型也不必一样,只要能用==比较即可。

1.2 写容器元素的算法
(1)fill()算法

fill(vec.begin(), vec.end(), 0);// 将每个元素重置为0
fill(vec.begin(), vec.begin() + vec.size()/2, 10);// 将容器的一个子序列设置为10

(2)fill_n()算法

vector<int> vec;
fill_n(vec.begin(), vec.size(), 0);// 将所有元素重置为0

函数fill_n()假定写入指定个元素是安全的,调用方式为

fill_n(dest, n ,val)

fill_n假定dest指向一个元素,而从dest开始的序列至少包含n个元素。

(3)back_inserter
插入迭代器(back_inserter)能保证算法有足够元素空间来容纳输出数据。back_inserter接受一个指向容器的引用,返回一个与该容器绑定的插入迭代器。通过此迭代器赋值时,赋值运算符会调用push_back将一个具有给定值的元素添加到容器中。

vector<int> vec;//空向量
auto it = back_inserter(vec);//通过它赋值会将元素添加到vec中
*it = 42;//vec中现在有一个元素42

我们常常使用back_inserter来创建一个迭代器作为算法的目的位置来使用。

vector<int> vec;//空向量
fill_n(back_inserter(vec), 10, 0);//添加10个元素到vec

(4)copy()算法
拷贝(copy)算法是向另一个目的位置迭代器指向的输出序列中的元素写入数据的算法。此算法接受三个迭代器,前两个表示一个输出范围,第三个表示目的序列的起始位置。

int a1[] = {0,1,2,3,4,5,6,7,8,9};
int a2[sizeof(a1)/sizeof(*a1)];//a2与a1大小一样
auto ret = copy(begin(a1), end(a1), a2);//把a1的内容拷贝给a2,ret恰好指向拷贝到a2的尾元素之后的位置

(5)replace()算法和replace_copy()算法
replace算法接受四个参数:前两个是迭代器,表示输入序列,后两个一个是要搜素的值,另一个是新值,它将所有等于第一个值的元素替换成第二个值。

replace(ilst.begin(), ilist.end(), 0, 42);//将所有值为0的元素改为42

如果我们希望保留原序列不变,可以调用replace_copy。此算法接受额外三个迭代器参数,指出调整后序列的保存位置。

replace_copy(ilst.cbegin(), ilist.cend(), back_inserter(ivec), 0, 42);//将所有值为0的元素改为42

1.3 重排容器元素的算法
消除重复单词:

void elimDups(vector<string> &words)
{
	//按字典序排序words,以便查找重复单词
	sort(words.begin(), words.end());
	//unique重排输入范围使得每个单词只出现一次,排列在范围的前部,返回指向不重复区域之后一个位置的迭代器
	auto end_unique = unique(words.begin(), words.end());
	//使用向量操作erase删除重复单词
	words.erase(end_unique, words.end());
}

1.4 定制操作

*【注】如果你觉得此文不错,可以考虑打赏我哦,您的打赏将是我更新的最大动力,非常感谢。(打赏也是基于自愿原则的哦( ̄︶ ̄))

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值