Effective STL 学习笔记 Item 30: 保证目标区间足够大

*/-->

div.org-src-container {
font-size: 85%;
font-family: monospace;
}
p {font-size: 15px}
li {font-size: 14px}

1 容器区间与算法

STL 容器吸引人的地方之一在于它能够自动管理内存,在有新的元素插入时候(通过 push_back(),
push_front(), insert()
)可以自动分配空间。但要注意的是,如果新的元素不是通过上述的 navive
method
加进来的话,容器不会自动分配内存,例如下面的代码:

1: int transmogrify(int x); // this function produces some new value from x.
2: vector<int> values;
3: vector<int> results
4:
5: transform(values.begin(), values.end(), results.end(), transmogrify);

这里有两个问题:

  • 第五行代码会直接向 results 的尾部写入数据,而尾部的内存未知,会引发问题
  • 直接的操作不会改变容器内部记录的 size & capacity ,从而破坏的容器。

2 back_inserter

我们应该想办法调用 push_front,push_back or insert 来插入数据:

int transmogrify(int x); // this function produces some new value from x.
vector<int> values;
vector<int> results transform(values.begin(), values.end(), back_inserter(results), transmogrify);

3 front_inserter

如果上面的代码中使用的是可以双向插入数据的容器( deque or list ),还可以使用
push_front :

1: int transmogrify(int x); // this function produces some new value from x.
2: list<int> values;
3: list<int> results
4:
5: transform(values.begin(), values.end(), front_inserter(results), transmogrify);

上面的代码还有个问题,由于每个数据都会被插到头部,实际上最后得到的 results 里面数据的顺序和
values 里面是相反的,我们可以反向遍历 values:

int transmogrify(int x); // this function produces some new value from x.
list<int> values;
list<int> results transform(values.rbegin(), values.rend(), front_inserter(results), transmogrify);

4 inserter

front_inserter & back_inserter 可以向前或者向后插入数据,而 inserter 则可以向任意位置插入数据:

int transmogrify(int x); // this function produces some new value from x.
vector<int> values;
vector<int> results transform(values.begin(), values.end(),
inserter(results, results.begin() + results.size()/2),
transmogrify);

5 inserter & reserve

Item 14 中提到过,vector 插入式数据可能会引起内存的重新分配,从而影响性能,对于前面的几个例子来说,我们可以预先算出插入新的数据后 vector 有多大,因此可以是所有 Item 14 中提到过的方法来优化:

int transmogrify(int x); // this function produces some new value from x.
vector<int> values;
vector<int> results result.reserve(result.size() + values.size());
transform(values.begin(), values.end(),
inserter(results, results.begin() + results.size()/2),
transmogrify);

Effective STL 学习笔记 Item 30: 保证目标区间足够大的更多相关文章

  1. Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据

    Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据 */--> div.org-src-container { font-size: 85%; font-fam ...

  2. Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value

    Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value */--> div.org-src-container ...

  3. Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor

    Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor */--> div ...

  4. Effective STL 学习笔记 Item 21:Comparison Function 相关

    Effective STL 学习笔记 Item 21:Comparison Function 相关 */--> div.org-src-container { font-size: 85%; f ...

  5. Effective STL 学习笔记 Item 17: Swap Trick

    假设有若干对象存于一个 vector 中: class Widget; vector<Widget> vw; 后来由于某些原因,从该容器中删除了若干对象(参考erase-remove id ...

  6. Effective STL 学习笔记 Item 16:vector, string & C API

    有时需要支持 C 的接口,但这并不复杂. 对于 vector 来讲, \(v[0]\) 的地址 \(\&v[0]\) 即可作为数组指针传递给 C API: 1: // Legacy C API ...

  7. Effective STL 学习笔记 Item 18: 慎用 vector<bool>

    vector<bool> 看起来像是一个存放布尔变量的容器,但是其实本身其实并不是一个容器,它里面存放的对象也不是布尔变量,这一点在 GCC 源码中 vector<bool> ...

  8. [置顶] Effective STL 学习笔记

    看Effective STL 作的一些笔记,希望对各位有帮助. 以下是50条条款及相关解释. 容器 1. 慎重选择容器类型,根据需要选择高效的容器类型. 2. 不要试图编写独立于容器类型的代码. 3. ...

  9. Effective STL 学习笔记: Item 22 ~ 24

    Effective STL 学习笔记: Item 22 ~ 24 */--> div.org-src-container { font-size: 85%; font-family: monos ...

随机推荐

  1. 并发库应用之二 & Java原子性操作类应用

    Java5的线程并发库中,提供了一组atomic class来帮助我们简化同步处理.基本工作原理是使用了同步synchronized的方法实现了对一个long, integer, 对象的增.减.赋值( ...

  2. 1082 线段树练习 3 && 树状数组区间修改区间查询

    1082 线段树练习 3 题意: 给定序列初值, 要求支持区间修改, 区间查询 Solution 用树状数组, 代码量小, 空间占用小 巧用增量数组, 修改时在 \(l\) 处 $ + val$ , ...

  3. Nginx跳转Tomcat

    conf配置: server {         listen       80;         server_name www.-------.com;         server_name_i ...

  4. OpenResty 扩展库之(一)——lua-resty-shell 库

    介绍 当您需要执行子进程(或shell命令)时,这是一个打算与OpenResty应用程序一起使用的小型库. 它类似于os.execute和io.popen,除了它是完全非阻塞的,因此即使对于需要很长时 ...

  5. 线搜索(line search)方法

    在机器学习中, 通常需要求某个函数的最值(比如最大似然中需要求的似然的最大值). 线搜索(line search)是求得一个函数\(f(x)\)的最值的两种常用迭代方法之一(另外一个是trust re ...

  6. 实验九 Web安全基础

  7. 【转】线程间操作无效: 从不是创建控件“textBox2” 的线程访问它。

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...

  8. JavaScript基本运算

    JavaScript基本运算 JavaScript:其实它的基本运算和我们数学的基本运算类似的. --------------------------------------------------- ...

  9. transform动画效果

     transform动画效果 transform :移动,旋转.倾斜.缩放.     transform:translate(0,300px); x代表的是水平的偏移距离,y代表垂直的.      t ...

  10. 在window 8 或windows2012 上用命令行安装framework3.5 方法

    找到对应操作系统安装目录的sources文件夹下的sxs文件夹,拷贝到本地电脑,如F:盘 根目录下 CMD(管理员身份)命令: dism.exe /online /enable-feature /fe ...