43. 算法调用优先于手写的循环
STL算法涉及面很广,这意味着你本该编写循环来完成的任务也可以用STL算法来完成。
例如,有一个Widget类:
class Widget
{public:...void redraw() const;...
};
当你想在一个包含Widget的list中调用所有成员的Widget对象,可以用一个循环来完成,
std::list<Widget> datas;
...
for (auto iter = datas.begin(); iter != datas.end(); ++iter)
{iter->redraw();
}
你也可以选择使用for_each算法来完成:
for_each(datas.begin(), datas.end(), mem_fun_ref(Widget::redraw));
编写一个循环比调用一个算法更在简单,但事实上调用算法通常是更好的选择,它往往优先于任何一个手写循环。理由有三:
- 效率:算法通常比自己学的循环效率更高。
- 正确性:手学循环比使用算法更容器出错。
- 可维护性:使用算法的代码通常比手写循环的更加简洁明了。
从效率看:
使用算法可以减少冗余的计算。
对于循环:
for (auto iter = datas.begin(); iter != datas.end(); ++iter)
{iter->redraw();
}
每一次循环的额时候,list::end()都要被调用。但是并不需要多次调用它,因为并没有改变list。
如果使用算法:
std::for_each(datas.begin(), datas.end(), mem_fun_ref(&Widget::redraw()));
STL的实现者很清楚,begin、end都是被频繁调用的函数,所以他们尽可能提高其效率,几乎可以肯定会使用inline来编译这些函数,并且努力改善这些函数的代码,尽可能让大多数编译器都能够将循环中的计算提到外面来,避免重复计算。
类库实现者可以根据他们对容器实现的了解程度对遍历过程进行优化,这是库的使用者难以做到的。无论如何实现者肯定比调用者更了解内部的实现细节,他们可以在算法实现中充分利用这些知识。如果你避开算法使用自己的手写循环,你也就放弃了这些算法实现者可能提供的优化手段。
除了一些不太重要的算法之外,其他几乎所有的算法都使用了复杂的计算机科学算法,有些非常复杂,并非一般的程序员所能够达到。
从正确性看:
当你编写循环代码的时候,最紧要的莫过于与要保证你所使用的迭代器都是有效的,并且指向你所希望的地方。
从清晰度看:
最好的代码时最简洁、可读性最好的软件,是最容器扩展功能、最容易维护和适用于新环境的软件,尽管我们对循环更为熟悉,但是从长远上看,算法更具竞争力。
当你看到for、while或do的时候,你所知道的只不过是某一种循环将要出现。要想知道这个循环的用途,哪怕时最初略的用途,你都必须检查具体的代码。但是,当你看到了一个算法调用的时候,它的名称就会指出它的用途。当然,如果你想知道它到底做了什么,你必须检查哪些传给算法的实参的意义,但这通常比看懂一个循环结果的意图要简单得多。
在算法调用与手写循环中的斗争中,关于代码清晰度的底线最终取决于你要在循环中做什么事情。如果你要做的工作与一个算法所实现的功能很相近,那么用算法调用更好。如果你的循环很简单,若使用算法来实现的话,却要求混合使用绑定器或者一个单独的函数子类,那么,手写循环可能更好。最后,如果你在循环中要做的事情很多,而且很复杂,则最好使用算法调用,因为冗长又复杂的计算任务总是应该被放到单独的函数中。而一旦你把循环体移动到单独的函数中,你总是可以找到一个函数传给算法(例如for_each),这样得到的代码有直接、又清楚。
使用STL的精巧的C++程序比不用STL的程序所包含的循环要少得多,这是一件好事。任何时候我们都应该尽量用较高层次的insert、find和for_each来替换较低层次的for、while和do。因为这样可以提高软件的抽象层次,从而使软件更易于编写,更易于文档化,也更易于扩展和维护。
43. 算法调用优先于手写的循环相关推荐
- 16.算法调用优先于手写的循环
STL算法涉及面很广,这意味着你本该编写循环来完成的任务也可以用STL算法来完成. 例如,有一个Widget类: class Widget { public:...void redraw() cons ...
- 多元线性回归算法python实现_手写算法-Python代码推广多元线性回归
1.梯度下降-矩阵形式 上篇文章介绍了一元线性回归,包括Python实现和sklearn实现的实例.对比,以及一些问题点,详情可以看这里: 链接: 手写算法-Python代码实现一元线性回归 里面封装 ...
- 使用kNN算法实现简单的手写文字识别
0. 介绍 kNN,即k-Nearest Neighbor(k近邻算法), 简介可参考KNN的一些总结. 本文是<机器学习实战>一书第二章的例子, 主要利用kNN实现简单的手写文字识别. ...
- Apriori算法详解及手写案例
大家好,我是W 在数据挖掘中有一种关联分析算法叫做Apriori算法,大家可能都听说过啤酒尿布的故事,购买尿布的爸爸很可能会再去购买一份啤酒来犒劳自己,在大数据的背景下已经无法使用人工的方法去发现海量 ...
- 计算机风格学,由风格学习算法自动生成大规模手写字体
北大计算机研究所(http://www.icst.pku.edu.cn/content/content_6622.htm) - 计算机所连宙辉老师参加SIGGRAPH Asia 论文:Automati ...
- 用python写行列式_用Python开发线性代数算法(一) | 手写行列式算法的实现
和往年不同,今年的"五一"假期,没有出去游玩.一个原因是疫情还没有过去,小心点为好:另一个原因就是最近天气太热,懒得出门 .当然了,不出门也不能窝在被窝里看片儿,作为四十多岁的大叔 ...
- 通过Python调用QQAI做手写OCR识别并导出结果字段到excel里
有个需求:现场需要根据打印的表格手工填写好内容,然后再在电脑上一个个录入进去,费时费力,所以想是否可以通过程序把照片内需要的数据读取出来并导出到excel表格里. 网上找了一下教程,目前百度AI和QQ ...
- 前端小插件之手写js循环滚动特效
很多前端都离不开滚动的特效,调用插件繁琐,后期更改麻烦,考虑到这些因素,自己写了一套无限循环滚动的小特效. 首先滚动特效很好写,用css就可以完成,下面写一个基础css向上循环滚动特效 html &l ...
- 【Android 异步操作】手写 Handler ( 循环者 Looper | Looper 初始化 | Looper 遍历消息队列 MessageQueue )
文章目录 一.Looper 初始化 二.Looper 遍历消息队列 MessageQueue 三.完整 Looper 代码 一.Looper 初始化 Looper 是 线程本地变量 , 在每个线程中 ...
- Python手写线性回归算法
作者 | 苏南下 来源 | 机器会学习ML(ID:AI_Learning007) 摘要:通俗易懂介绍线性回归算法,并 Python 手写实现. 之前我们介绍了:kNN 算法,主要用于解决分类问题,也可 ...
最新文章
- 多视图关联选择的例子
- DCMTK:将XML文档转换为DICOM文件或数据集
- php redis新增数据类型,Redis有哪几种数据类型
- unity3d 地面印花_unity怎么实现挖掘泥土?
- Spring入门(四)之BeanFactory
- linux安装中文输入法sc,Linux下安装Discuz_7.2_FULL_SC_GBK
- [转]ASP.net(c#)生成条形码
- android build获取ext,顶级build.gradle文件中的ext属性
- Python Tricks(二十一)—— 排列组合的计算
- vb连接mysql数据库报错_vb6连接mysql数据库
- H264封装为FLV
- Arcface训练vgg2face数据集——数据制作
- 万物皆对象,你信吗?
- 诚之和:一年过去了,蚂蚁集团IPO“批文”到期!再上市需重新“排队”
- 通过调用ffmpeg来将mp3和jpg合并为mp4视频-批处理。
- 获取微信好友头像,对其进行相应操作
- ajax treegrid 选中,easyui treeGrid异步加载子节点示例
- 大数据框架hadoop之JobTracker主要功能分析
- Teigha绘制“月亮”形状
- html5+canvas+九宫格,javascript+canvas制作九宫格小程序