c++: 实战详解vector

2023-11-13

目的

本文从实际使用的角度出发,简介C++中vector的基本用法,如增,删,改,查等,并举例说明。

如下代码演示如何向vector中添加元素,其中:

#include <iostream>
#include <vector>

#include <iostream>
#include <vector>

int main() {
    std::vector<int> ilist;
    ilist.push_back(1);
    ilist.emplace_back(5); // append last
    ilist.insert(ilist.begin(), 3); // insert first
    ilist.emplace(ilist.begin(), 2);

    return 0;
}
  • push_back()和emplace_back()方法都是向数组末尾插入元素。
  • insert()方法和emplace()方法都接受数组的迭代器(上例中完整的类型为std::vector::iterator)作为插入的位置信息。其中begin()方法返回迭代器,表示数组的首地址。
  • insert()和emplace()方法的区别是emplace()方法可以帮助构建对象,因此对性能有点儿帮助,如下例中所示。
class Student {
    public: Student(std::string name) { }
};

int main() {
    std::vector<Student> slist;
    slist.push_back(Student("hello"));
    slist.emplace_back("hello");

    return 0;
}

通过erase()方法可以删除迭代提所指向的某个数据,如删除vector的第一个数据:

std::vector<int> ilist = { 1, 2, 3 };
ilist.erase(ilist.begin());

或者通过erase()方法删除连续的几个数据,如下把数组的前三个数据都删除:

std::vector<int> ilist = { 1, 2, 3, 4, 5 };
ilist.erase(ilist.begin(), ilist.begin() + 3);

在数据中查找具体的值然后删掉也经常会用到,如下代码片段将数组中所有的3删除:

std::vector<int> ilist = { 1, 2, 3, 3, 5 };

std::vector<int>::iterator i = ilist.begin();
while (i != ilist.end()) {
    if (*i == 3)
        i = ilist.erase(i);
    else
        i++;
}
  • erase()方法会返回下一个迭代器。
  • 这里用while比用for好写点儿,因为erase()可能会返回end(),在for的++中容易crash。

如果觉得写起来很麻烦的话,用stl 的algorithm 中的remove()方法也可以把所有值为3的数据删除:

#include <algorithm>

std::vector<int> ilist = { 1, 2, 3, 3, 5 };
ilist.erase(std::remove(ilist.begin(), ilist.end(), 3), ilist.end());

使用stl 的algorithm 中的remove_if()方法与lambda的组合可以更灵活的删除vector中的数据,如下删除所有>3的数据:

std::vector<int> ilist = { 1, 2, 3, 3, 5 };

auto removeLambda = [](int number) -> bool {
    return number > 3;
};
ilist.erase(std::remove_if(ilist.begin(), ilist.end(), removeLambda), ilist.end());

使用下标运算符[]修改数据中的数据:

std::vector<int> ilist = { 1, 2, 3, 3, 5 };
ilist[0] = 3;

或者使用迭代器指针与*运算符修改:

std::vector<int> ilist = { 1, 2, 3, 3, 5 };
auto i = ilist.begin();
*i = 3;

使用数组下标在for循环中查找所有为3的数据:

std::vector<int> ilist = { 1, 2, 3, 3, 5 };
for (int i = 0; i < ilist.size(); i++) {
    if (ilist[i] == 3) {
        // TODO FIND IT
    }
}

或者使用迭代器查找,一般来说,C++中的迭代器使用!=运算符作为终止条件,不像下标使用<:

std::vector<int> ilist = { 1, 2, 3, 3, 5 };
for (auto i = ilist.begin(); i != ilist.end(); i++) {
    if (*i == 3) {
        // TODO FIND IT
    }
}

感谢C++11的语法,有了更简介的for循环用法:

std::vector<int> ilist = { 1, 2, 3, 3, 5 };
for (auto i : ilist) {
    if (i == 3) {
        // TODO FIND IT
    }
}
  • 需要注意的是,auto i : ilist中的i需要发生一次数据拷贝。
  • 使用auto &i : ilist可以避免数据的拷贝,如果vector中存放的是unique_ptr, 这会很有用,因为只能这么写:)。

排序

使用stl 的algorithm 中的sort()方法对数组做升序排列,使用reverse()方法做降序排列。

std::vector<int> ilist = { 3, 2, 7, 5, 9};
std::sort(ilist.begin(), ilist.end());

如果vector中存放了自定义的类型,恰好又没有重载>或者<运算符的话,sort()数据也可以接收自定义的排序函数或者使用lambda:

std::vector<int> ilist = { 3, 2, 7, 5, 9};
std::sort(ilist.begin(), ilist.end(),
          [](int a, int b) { return a > b; });

总结

  • 新版本的c++标准容器中已经可以存放unique_ptr了。

引用

[1] https://stackoverflow.com/questions/9025084/sorting-a-vector-in-descending-order
[2] https://en.cppreference.com/w/cpp/algorithm/remove
[3] https://stackoverflow.com/questions/5122804/how-to-sort-with-a-lambda

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++: 实战详解vector 的相关文章

随机推荐

  • DGL-kernel的变更(3)

    导读 DGL kernel中针对Graph的计算几个版本有了不小的变动 v0 3 0 4使用的是minigun v0 3和v0 4源码中主要相关部分则是在对应分支dgl src kernel目录下 v0 5中对kernel代码进行了重写 并
  • IOS学习笔记(十二)之IOS开发之表视图(UITableView)的相关类,属性与表视图实现学习(二)

    iOS学习笔记 十二 之IOS开发之表视图 UITableView 的讲解与使用 二 博客地址 http blog csdn net developer jiangqq 转载请注明地址 Author hmjiangqq Email jian
  • 记录一个问题maven jar 引入

    分模块创建项目jar包无法引入错误 明明在 确保错 无奈最后换个本地仓库地址 重新下载jar 结果不报错了 估计是jar包太多了 混乱导入造成的
  • MySQL中tinyint(1)与tinyint(2)的区别

    一 tinyint类型的介绍 1个tinyint类型的字段占用一个字节 一个int类型的字段占用四个字节 CREATE TABLE user id int 11 NOT NULL COMMENT ID age tinyint 1 NOT N
  • nginx配置SSL协议,80端口443端口。和非80/443端口

    1 80 443 server listen 80 server name www 域名 com rewrite https server name 1 permanent server listen 443 server name www
  • 前端项目查找网站有哪些?面试必看

    教你们一招 项目在这些地方找 面试官眼前一亮 还有一些面试技巧 收藏 工作年限 3 年工作经验 5个项目以上 2 年工作经验项目 4 个项目 技术栈 Vue vuex vue router webpack ES6 node vue reso
  • 兔子问题---细说斐波那契数列

    对于兔子问题的鼎鼎大名 相信很少有人没听过吧 为了完整性还是再说一下题目吧 题目描述 已知一对兔子每一个月可以生一对小兔子 而一对兔子出生后 第三个月开始生小兔子假如一年内没有发生死亡 则一对兔子开始 第N个月后会有多少对 这道题所描述的就
  • 解决IDEA2019.1.3无法创建包的子类包问题

    有时候我们需要创建包的子类包 空包 的时候我们发现 不知道如何在初始的包中创建子类包 随后在别的博客上看了好多解决方法 好多都是没有选中父类包 或者没有将下面这个选项勾掉 但是这个勾掉的话就把父类中最后一个包也变成了子类包 并没有达到我们所
  • “先裁掉女员工!”

    身为女性在职场 不得不面对一些尴尬的时刻 我朋友公司刚招了一个商务的妹纸 没几周就说自己怀孕了 紧接着 开启了三天打鱼两天晒网的请假模式 今年就业环境不太理想 朋友公司招人有严格的名额限制 考虑再三 上司和HR昨天找她面谈 上司说 市场岗压
  • leveldb 源码--总体架构分析

    一 本文目的 对leveldb的总体设计框架分析 关于leveldb基本原理 此文不做阐述 读者可以自行检索文章阅读即可 对leveldb中底层数据存储数据格式 内存数据模型 compact 版本管理 快照等机制实现介绍以及整个leveld
  • 弯道超车,阿里高工新产Java面试速成指南,面试骚操作都在里面了

    金三银四过去一半 市场火热 但是大家就业压力却没有缓解多少 很多粉丝后台留言 Java程序员面临的竞争太激烈了 我自己也有实感 多年身处一线互联网公司 虽没有直面过求职跳槽的残酷 但经常担任技术面试考官 对程序员招聘市场的现状很清楚 导致现
  • C++中.cpp和.hpp的区别

    时间 2020 06 02 标签 c cpp hpp 区别 栏目 C C 繁體版 原文 https my oschina net u 4398200 blog 3336507 原文地址 https blog csdn net qzx9059
  • H5中写一个下拉框,点击下拉框内容会出现在文本域中

    朋友出去面试做的面试题 分享了下 我就拿来做做 原题 HTML中有个下拉框 包含 风 雨 雷 电 添加事件 当选择风时 文本域内出现选择
  • 使用proteus仿真集成运放构成的三角波发生电路

    仿真电路图 仿真示波器结果
  • 用python做小游戏——以弹球游戏为例

    本博客使用了Pygame库来创建游戏窗口和处理游戏逻辑 一 代码详细解释 首先 通过调用pygame init 来初始化Pygame库 然后创建一个窗口并设置标题 pygame init screen pygame display set
  • 当全景视频遇到快手

    收到 山巅之处 正午的阳光透过翻滚的云海铺洒在岩石壁上 镶嵌在天边连绵起伏的山峦若隐若现 雄伟壮观 俯瞰去 脚下是天梯般陡峭的山崖 连接着山中绿洲 纵身一跃 映入眼帘的是逐渐清晰的林海 那些拔地而起的树木紧密相连 铸成一座郁郁葱葱的 绿色长
  • docker容器内服务访问宿主机服务

    我的个人博客 逐步前行STEP 本文背景 操作系统 macOs 笔者的docker虚拟机中运行了nginx node服务用来部署一个前后端分离的网站 但是由于docker内的node服务运行效率极低 每次代码更新后也不会自动重新编译 所以准
  • 函数间隔和几何间隔

    问题描述 求一个任意点 到一个超平面的距离 超平面表示 在线性代数中 一个超平面可以用下式表示 y X W T
  • 借助ChatGPT自动生成PPT

    借助ChatGPT自动生成PPT 首先让GPT生成一段markdown格式的PPT内容 尽量描述全面 以什么语言 什么格式 排版等等 打开mindshow网址 点击import and create 选择以markdown方式创建 再次点击
  • c++: 实战详解vector

    目的 本文从实际使用的角度出发 简介C 中vector的基本用法 如增 删 改 查等 并举例说明 增 如下代码演示如何向vector中添加元素 其中 include