# 第5章 STL基础算法

STL不仅包含数据结构，还有很多算法。数据结构可以帮助存放特定情况下需要保存的数据，而算法则会将数据结构中存储的数据进行变换。

让我们来看一个标准的例子，例如对`vector`实例中的数据进行累加。这个可以简单的通过循环迭代`vector`中的元素，将所有值累加在一个对应的值上：

```cpp
vector<int> v {100, 400, 200 /*, ... */ };

int sum {0};
for (int i : v) { sum += i; }

cout << sum << '\n';
```

不过，作为一个标准的例子，当然可以使用STL的算法来完成：

```cpp
cout << accumulate(begin(v), end(v), 0) << '\n';
```

例子中循环变量也不是很长，不过其可读性比`accumulate`差很多。一个10行的循环代码看起来的确很尴尬，那么本章我们就看来了解一下标准算法(`accumulate`, `copy`, `move`, `transform`和`shuffle`等等)的工作机制。

其思想就是提供丰富的算法供开发者使用，避免耗费大量的时间在重复制造轮子上面。另一方面就是，即便开发者会自己去实现相应STL中的算法，也要进行大量的测试来确保自己实现的算法是否正确，STL提供的算法都是经过了严格的测试。所以没有必要做重复的工作，这样也能节省代码审阅者的时间，否则他们还要确定算法实现中是否有Bug。

另一个重点是STL算法非常的高效。很多STL算法提供了多种特化实现，这样足以应对依赖迭代器类型的使用方式。例如，将`vector`中的所有元素都填充0时，就可以使用`std::fill`。因为`vector`使用的是一段连续的内存，对于这种使用连续内存存放数据的结构都可以使用`std::fill`进行填充，这个函数类似于C中的`memset`函数。当开发者将容器类型从`vector`改为`list`，STL算法就不能再使用`memset`了，并且需要逐个迭代list的元素，并将元素赋0。开发者不能为了使用`memset`将数据类型写死为`vector`或`array`，因为实际项目中，还是有很多数据结构存储的地址并不是连续的。大多数情况下，想要自己去将代码实现的更聪明是没有太多意义的，因为STL的实现者已经考虑到了这种情况，并且STL还是免费使用的，为什么不用呢？

让我们总结一下前面提到的几点。使用STL算法的好处：

* **维护性**：算法的名字已经说明它要做什么了。显式使用循环的方式与使用STL算法的方式没法对比。
* **正确性**：STL是由专家编写和审阅过的，并且经过了良好的测试，重新实现的复杂程度可能是你无法想象的。
* **高效性**：STL算法真的很高效，至少要比手写的循环要强许多。

很多算法都是对迭代器进行操作，第3章已经解释了迭代器的工作原理。本章专注于如何使用STL算法解决各种问题，了解这些STL应该如何使用。要展示所有STL算法的使用方式不是本书所要做的事情，这个事情C++手册已经完成了，你可以在网上进行查询，或者花钱购买电子/纸质发布版本。

作为一个STL“忍者”需要将C++手册放在手边……嗯，至少放在浏览器的书签中吧。当我们在完成一个任务的过程中，每个开发者都可以回看一下任务本身，在完成自己的任务时，确定这个STL算法是否适合于你的问题。

在线版本的C++手册：<http://cppreference.com>

其也提供离线下载功能。

> Note:
>
> 在面试过程中，对于STL算法的熟悉程度也是判断一个开发者对C++的熟悉程度的标准之一。
