Effective STL:5、算法


这在第 1 章开始的时候提到过,在 STL 中最受欢迎的就要数容器了。这点很容易理解 —— 容器无疑是 STL 最重要的成就之一,它极大地简化了众多 C++ 程序员的日常编程工作。同样地,STL 算法也有此殊荣,因为它同样能够显著地减轻程序员的负担。事实上,STL 中只有 8 个容器类,却包含超过 100 个算法,所以,毫无疑问,STL 算法为程序员提供了更为锐利的工具。但其庞大的数量同时也成为学习的障碍,记住 70 个算法的名字和功能比熟悉 8 个不同的容器类要困难得多。


本章有两个主要目标。第一,我将向你介绍 STL 中一些鲜为人知的算法,以及如何使用这些算法来简化工作。我不会只是简单地罗列这些算法的名字,凡是本章中我向你展示的算法,都可以解决一些非常常见的问题,比如:忽略大小写的字符串比较、有效地找到容器中最合适的 n 个对象、容器中一个区间内所有对象的统计处理,以及实现一个功能类似于 copy_if 的算法(最初的 HP STL 中实现了 copy_if,但在标准化过程中被删除了)。


我的第二个目标是告诉你应该如何避免在 STL 算法使用上的一些通病。比如,你必须非常清楚remove、remove_if 或者 unique 做了什么事情(以及没做什么事情),否则就不要调用这些算法。当要删除的区间中包含了指针的时候,这显得尤为重要。类似地,有许多算法要求排序的区间,所以,你需要知道哪些算法有这样的要求,为什么它们要强加这样的限制。最后,一个与 STL 算法相关的最常见的错误是,要求 STL 算法将结果写到一个并不存在的地方。我会详细解释这种错误是怎么来的,以及如何避免这样的错误。


即使阅读了本源之后,你对 STL 算法的印象也许仍然不及容器那样深刻,但我想你会比过去更加注重 STL 算法。



第30条:确保目标区间足够大


当有新的对象被加进来的时候,STL 容器会自动扩充存储空间以容纳这些对象。这是一个非常不错的特性,以至于许多程序员会误以为 STL 容器总是能够正确地管理它的存储空间,而不用他们操心,可惜事实并非如此。



第31条:了解各种与排序有关的选择


对排序算法的选择应该更多地基于你所需要的完成的功能,而不是算法的性能。如果你选择的算法恰好能完成你所需要的功能,那么多数情况下,这不仅可以使你的代码更加清晰,而且也是用 STL 来完成相应功能的最有效途径。



第32条:如果确实需要删除元素,则需要在 remove 这一类算法之后调用 erase


因为从容器中删除元素的唯一方法是调用容器的成员函数,而 remove 并不知道它操作的元素所在的容器,所以 remove 不可能从容器中删除元素。

这也说明了一个现象:用 remove 从容器中删除元素,而容器中的元素数目却不会因此而减少。



第33条:对包含指针的容器使用 remove 这一类算法时要特别小心


无论你如何处理那些存放动态分配的指针的容器,总是可以这样来进行:或者通过引用技术的智能指针,或者在调用 remove 类算法之前先手工删除指针并将它们置为空,或者用你自己发明的其他某项技术。



第34条:了解哪些算法要求使用排序的区间作为参数


有些算法要求排序的区间,即区间中的值是排过序的。当使用这些算法的时候,遵循这条规则尤为重要,因为违反这一规则并不会导致编译错误,而会导致运行时的未确定行为。



第35条:通过 mismatch 或 lexicographical_compare 实现简单的忽略大小写的字符串比较


strcmp/strcmpi 通常是被优化过的,它们在长字符串的处理上一半要比通用算法 mismatch 和 lexicographical_compare 快得多。



第36条:理解 copy_if 算法的正确实现


其实 copy_if 是很有用的,很多 STL 程序员都希望有这个算法。你可以把这个正确的 copy_if 放到你本地的 STL 相关的工具库中,然后在适当的地方使用这个算法。



第37条:使用 accumulate 或者 for_each 进行区间统计


从我个人的观点来看,我宁愿使用 accumulate,因为我认为它清楚地表达了所要做的事情,当然 for_each 也能工作,而且副作用的问题对于 for_each 来说,也没有 accumulate 那样严重。两个算法都能用于统计区间,你可以从中挑选最适合你的算法。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值