罗剑锋的C++实战笔记16-五花八门的算法:不要再手写for循环了

上节课我提到了计算机界的经典公式“算法 + 数据结构 = 程序”,公式里的“数据结构”就是 C++ 里的容器,容器我们已经学过了,今天就来学习下公式里的“算法”。

虽然算法是 STL(标准库前身)的三大要件之一(容器、算法、迭代器),也是 C++ 标准库里一个非常重要的部分,但它却没有像容器那样被大众广泛接受。

从我观察到的情况来看,很多人都会在代码里普遍应用 vector、set、map,但几乎从来不用任何算法,聊起算法这个话题,也是“一问三不知”,这的确是一个比较奇怪的现象。而且,很多语言对算法也不太“上心”。

但是,在 C++ 里,算法的地位非常高,甚至有一个专门的“算法库”。早期,它是泛型编程的示范和应用,而在 C++ 引入 lambda 表达式后,它又成了函数式编程的具体实践,所以,学习掌握算法能够很好地训练你的编程思维,帮你开辟出面向对象之外的新天地。

认识算法

从纯理论上来说,算法就是一系列定义明确的操作步骤,并且会在有限次运算后得到结果。

计算机科学里有很多种算法,像排序算法、查找算法、遍历算法、加密算法,等等。但是在 C++ 里,算法的含义就要狭窄很多了。

C++ 里的算法,指的是工作在容器上的一些泛型函数,会对容器内的元素实施的各种操作。

C++ 标准库目前提供了上百个算法,真的可以说是“五花八门”,涵盖了绝大部分的“日常工作”。比如:

remove,移除某个特定值;

sort,快速排序;

binary_search,执行二分查找;

make_heap,构造一个堆结构;

……

不过要是“说白了”,算法其实并不神秘,因为所有的算法本质上都是 for 或者 while,通过循环遍历来逐个处理容器里的元素。

比如说 count 算法,它的功能非常简单,就是统计某个元素的出现次数,完全可以用 range-for 来实现同样的功能:

vector<int> v = {1,3,1,7,5}; // vector容器

auto n1 = std::count( // count算法计算元素的数量

begin(v), end(v), 1 // begin()、end()获取容器的范围

);

int n2 = 0;

for(auto x : v) { // 手写for循环

if (x == 1) { // 判断条件,然后统计

n2++;

}

}

你可能会问,既然是这样,我们直接写 for 循环不就好了吗,为什么还要调用算法来“多此一举”呢?

在我看来,这应该是一种“境界”,追求更高层次上的抽象和封装,也是函数式编程的基本理念。

每个算法都有一个清晰、准确的命名,不需要额外的注释,让人一眼就可以知道操作的意图,而且,算法抽象和封装了反复出现的操作逻辑,也更有利于重用代码,减少手写的错误。

还有更重要的一点:和容器一样,算法是由那些“超级程序员”创造的,它的内部实现肯定要比你随手写出来的循环更高效,而且必然经过了良好的验证测试,绝无 Bug,无论是功能还是性能,都是上乘之作。

如果在以前,你不使用算法还有一个勉强可以说的理由,就是很多算法必须要传入一个函数对象,写起来很麻烦。但是现在,因为有可以“就地定义函数”的 lambda 表达式,算法的形式就和普通循环非常接近了,所以刚刚说的也就不再是什么问题了。

用算法加上 lambda 表达式,你就可以初步体验函数式编程的感觉(即函数套函数):

auto n = std::count_if( // count_if算法计算元素的数量

begin(v), end(v), // begin()、end()获
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员zhi路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值