C++ Primer学习笔记—— 泛用性算法

本文深入探讨了C++标准模板库(STL)中的关键算法,包括find、accumulate、equal、fill、sort、unique等,展示了如何利用这些算法进行高效的数据处理和操作。同时,文章还介绍了lambda表达式的灵活运用,以及mutable关键字在const上下文中的特殊作用。

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

#include<iostream>
#include<vector>
#include<numeric>
#include<algorithm>
#include<iterator>
#include<functional>
using namespace std;

auto fun0(int a, int b) -> bool
{
	return a < b;
}

void fun(int a) {
	//mutable  修饰类成员变量时,即使在const里也能改变这个变量
	cout << "构建lambda前: " << a << endl;
	auto f = [a]() mutable {return ++a; };//值传递时,捕获的变量不能修改,除非加上mutable
	cout << "构建lambda后: " << a << endl;
	auto aa = f();
	cout << "调用lambda后 a: " << a << endl;
	cout << "调用lambda后 aa: " << aa << endl;

}
void fun1(int a) {
	cout << "构建lambda前: " << a << endl;
	auto f = [&a]() mutable {return ++a; };//引用const类型时,也不能改,除非加上mutable
	cout << "构建lambda后: " << a << endl;
	auto aa = f();
	cout << "调用lambda后 a: " << a << endl;
	cout << "调用lambda后 aa: " << aa << endl;

}

int main()
{
	vector<int> A{ 0,1,2,3,4,5,6,7,8,9,10 };

	//find 查找 (要支持==)
	cout << "find:" << endl;
	auto resfind = find(A.begin(), A.end(), 5);
	cout << "The result is: " << ((resfind == A.end()) ? "Not Find" : "Find") << endl;
	//cout << *resfind << endl;	//find返回的是迭代器

	//accumulate 求和(支持+)<在numeric头文件中>
	cout << "accumulate:" << endl;
	auto sum = accumulate(A.begin(), A.end(), 0);//第三个参数是求和初始值,前两个是范围
	cout << "Sum: " << sum << endl;

	//equal 将前两个迭代器范围内的与第三个迭代器开始的同位置元素进行比较
	//若同位置元素相等,则返回true,否则返回false(要支持==,并假定第二个序列至少与第一个序列一样长)
	vector<int> B{ A };
	cout << "equal:" << endl;
	//B.erase(B.end()-1);//会报异常,因为第二个序列更短
	B.emplace_back(11);//返回true,因为第二个序列与第一个序列同位置元素相等
	cout << "A equal to B ? " << equal(A.begin(), A.end(), B.begin()) << endl;

	//fill填充	(fill填充不检查插入范围,程序员必须保证有足够的空间去fill)
	cout << "fill:" << endl;
	fill(B.begin(), B.end(), 0);
	for (const auto &m : B)
		cout << m << " ";
	cout << endl;

	//fill_n 填充 (也是不检查插入范围,若空间不够会抛异常)
	cout << "fill_n:" << endl;
	fill_n(B.begin(), 10, 9);//10是填充元素个数,9是填充的值
	for (const auto &m : B)
		cout << m << " ";
	cout << endl;

	//copy 拷贝(将第一个参数与第二个参数之间的序列拷贝至第三个参数的位置,
	//程序员必须保证目的序列有足够的空间存放copy过来的元素)
	cout << "copy:" << endl;
	copy(A.begin(), A.end(), B.begin());
	for (const auto &m : B)
		cout << m << " ";
	cout << endl;

	//replace 查找替换,与string类的replace的指定位置替换不同,
	//这里的replace是在前两个参数的范围中查找倒数第二个参数,并将其替换成倒数第一个参数
	//若是5个参数的replace_copy,则保持原序列不变,将替换后的结果保存至第三个参数的位置
	//使用replace_copy,程序员必须保证有足够空间存替换后的序列
	cout << "replace:" << endl;
	replace(B.begin(), B.end(), 0, 11);
	for (const auto &m : B)
		cout << m << " ";
	cout << endl;

	/*//此处抛异常,空间不够
	vector<int> C;
	replace_copy(B.begin(), B.end(), C.begin(), 11, 0);
	for (const auto &m : C)
		cout << m << " ";
	cout << endl;
	*/

	vector<int> C;//back_inserter生成插入迭代器,在iterator头文件中定义
	//通过push_back()实现插入
	cout << "replace_copy:" << endl;
	replace_copy(B.begin(), B.end(), back_inserter(C), 11, 0);
	for (const auto &m : C)
		cout << m << " ";
	cout << endl;
	//C有足够空间了 直接分配空间也行,	分配空间得用C.resize(12);不能用C.reserve(12);
	replace_copy(B.begin(), B.end(), C.begin(), 11, 10);
	for (const auto &m : C)
		cout << m << " ";
	cout << endl;
	
	//sort 与 unique
	//sort接收两个迭代器参数,即排序元素范围
	//unique也是接收两个参数,即消除重复元素的范围,unique是通过remove来消除重复的元素
	//因此,unique并不是真正把重复的元素删了,而是放在了容器尾部unique返回不重复元素序列的
	//后一个元素迭代器,此位置以及之后的元素仍然存在,只是我们不知道是什么,unique后要用erase真正删除
	cout << "sort 与 unique:" << endl;
	sort(C.begin(), C.end(), [](int a, int b)->bool {return a < b; });
	for (const auto &m : C)
		cout << m << " ";
	cout << endl;
	auto unique_iter = unique(C.begin(), C.end());
	C.erase(unique_iter, C.end());
	for (const auto &m : C)
		cout << m << " ";
	cout << endl;

	//stable_sort 与sort用法基本相同,唯一的区别是stable_sort排序后,相等元素的相对位置不变

	//for_each()  
	cout << "for_each:" << endl;
	for_each(C.begin(), C.end(), [](const int &a) {if (a > 5)	cout << a << " "; });
	cout << endl;

	//mutable  修饰类成员变量时,即使在const里也能改变这个变量
	cout << "mutable:" << endl;
	cout << "-----------捕获值----------" << endl;
	fun(1);
	cout << "--------捕获引用---------" << endl;
	fun1(1);

	//transform 接受三个迭代器和一个可调用对象,前两个迭代器表示输入序列,
	//第三个迭代器代表目的位置
	cout << "transform:" << endl;
	vector<int> D{ 0,1,-2,3,-4,5,-6 };
	//当只有一个return时,编译器能推断lambda返回类型,
	//有其他语句时返回void,书上这么说的,但可能编译器有优化,此处没有后置返回值的话也可以正常运行
	//transform(D.begin(), D.end(), D.begin(), [](int a) {return (a > 0 ? a : -a); });
	//transform(D.begin(), D.end(), D.begin(), [](int a) {a++; if (a > 0) return a; else return -a; });
	transform(D.begin(), D.end(), D.begin(), [](int a)->int { if (a > 0) return a; else return -a; });
	copy(D.begin(), D.end(), ostream_iterator<int>(cout, " "));
	cout << endl;

	//bind 接受一个可调用对象,生成另一个可调用对象,在functional头文件定义
	//auto newCallable=bind(callable,arg_list);
	//arg_list中形如_n是占位符,假如_n在arg_list的第m个位置(从1开始),那newCallable的第n个参数
	//就是callable中的第m个参数
	//_n定义在placeholders的命名空间中,而这个命名空间定义在std命名空间
	cout << "--------bind------------" << endl;
	int ff = 4;
	auto findif = bind(fun0, ff, placeholders::_1);
	//在bind中参数ff会拷贝到findif中,对于不支持拷贝的参数(比如流),我们希望直接传递引用,
	//因此可使用ref函数,表示返回对象的引用,若是用cref,则返回一个const引用
	//如auto findif = bind(fun0, ref(ff), placeholders::_1);
	auto finditer = find_if(A.begin(), A.end(), findif);
	while (finditer != A.end()) {
		cout << *finditer << " ";
		++finditer;
		finditer = find_if(finditer, A.end(), findif);
	}
	cout << endl;


	system("PAUSE");
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值