C++ STL容器 —— deque 用法详解

C++ STL容器 —— deque 用法详解

写在前面:近期正在学习C++的STL容器,因此在这里做一下日志记录,主要介绍一些容器基本成员函数的用法, 配上实际用例,并不涉及原理。但别人的博客终究是别人的, 最好自己上手操作一下.
写的不好, 请大神手下留情.

下面说的 “运行之后” 表示: 运行上个语句之后的结果.
一行如果说的太长的话, 就得拖动下面的进度条才能看到后面的内容, 非常麻烦
因此将一段话分成了多行,就像现在这种形式

简介

头文件:# include < deque >
动态双向数组,

与vector的区别
vector头部被封住了, 不能直接进行增删操作
deque两端都可以进行增删操作
具体表现在常用函数和 emplace 系列函数里面

点击前往: vector 函数用法详解

构造函数

deque <int> dv, dv1;
//定义 int 类型的数组

deque <char> dvch;
//定义 char 类型的数组

deque <string> dvstr;
//定义 string 类型的数组

deque <deque<int> > ddv;
//定义 int 类型的二维数组, 注意 '>' 之间需要有空格

deque <int> dv2(10);
//定义拥有 10 个元素的数组, 每个元素默认为 0

deque <int> dv3(5, 30);
//定义拥有 5 个元素的数组,并全部初始化为 30

deque <int> dv4{ 1,2,3,4 };
//定义拥有 4 个元素的数组, 初始化为{1,2,3,4}

deque <int> dv5 = { 1,2,3,4 };
//同上

deque <int> dv6(dv);
//定义新容器, 拷贝 dv 所有的元素

vector <int> dv7 = dv;
//同上

deque <int> dv8(dv.begin(), dv.end());
//定义新容器, 拷贝 dv 区间内所有的元素

访问 / 赋值

迭代器

包括: begin、end、rbegin、end、cbegin、cend、crbegin、crend
使用方法:

auto it=dv.begin(); //相当于指针,用 *it 访问

dv.begin(); 返回迭代器, 指向第一元素
dv.end(); 返回迭代器, 指向最末元素的下一个位置
dv.cbegin(); 返回迭代器, 指向第一元素, 类型为const
dv.rbegin(); 返回反向迭代器, 指向反向迭代的第一元素
dv.rend(); 返回反向迭代器, 指向反向迭代的最末元素的下一个位置
dv.crbegin(); 返回反向迭代器, 指向反向迭代的第一元素, 类型为const

例: 使用正向遍历 dv 数组

deque <int> dv{ 1,2,3,4,5,6 };
for (auto it = dv.begin(); it != dv.end(); it++) {
	//注意这里是不等于end, 而不是小于end
	cout << *it <<' ';
}
输出结果为: 
1 2 3 4 5 6

例: 反向遍历 dv 数组

deque <int> dv{ 1,2,3,4,5,6 };
for(auto it=dv.rbegin();it!=dv.rend();it++){
	//注意这里还是it++, 而不是it--
	cout << *it <<' ';
}
输出结果为: 
6 5 4 3 2 1

begin和rbegin的区别
dv.begin()返回迭代器,指向容器内的第一元素
dv.rbegin()返回逆序迭代器,指向容器内的最后一个元素

begin和cbegin的区别
可以通过dv.begin()修改容器内元素的值
不能通过dv.cbegin()修改容器内元素的值

下标 / at

支持下标 [] 和 at 函数随机访问容器内元素
dv[id]; 返回下标为 id 的元素, 不检查是否越界
dv.at(id); 返回下标为 id 的元素, 如果越界抛出异常

assign(赋值函数)

dv.assign(2, 3);
//将 2 个 3 赋值给 dv
//例:dv={5,6,7}
//运行之后 dv={3,3,3}

dv.assign(dv1.begin()+1, dv1.end()-1);
//将区间内的元素赋值给 v
//例:dv={5,6,7}, dv1={1,2,3,4}
//运行之后 dv={2,3}
swap (交换函数)
dv.swap(dv1);
//交换两个容器的内容
//例:dv={1,2,3,4}, dv1={5,6,7}
//运行之后, dv={5,6,7}, dv1={1,2,3,4}

常用函数

dv.push_front(4);
//在头部插入元素 4, vector 没有这个函数
//例:dv={1,2,3}
//运行之后, dv={4,1,2,3}

dv.push_back(4);
//在添加末端插入元素 4
//例:dv={1,2,3}
//运行之后, dv={1,2,3,4}

dv.pop_front();
//删除第一元素, vector 没有这个函数
//例:dv={1,2,3,4}
//运行之后, dv={2,3,4}

dv.pop_back();
//删除最末元素
//例:dv={1,2,3,4}
//运行之后, dv={1,2,3}

dv.front();
//返回第一元素
//例:dv={1,2,3,4}
//dv.front()就等于 1

dv.back();
//返回最末元素
//例:dv={1,2,3,4}
//dv.back()就等于 4

dv.clear();
//清空容器

dv.empty();
//容器为空返回true, 否则返回 false

长度 / 空间 / 容量相关函数

dv.size();
//返回容器内目前的元素个数
//例: dv={1,2,3}
//返回 3

dv.max_size();
//返回元素个数 size 的最大值
//返回一个数字, 根据编译环境的不同, 这个数字也不同, 基本没什么用.

dv.resize(3);
//设置 dv 的 size,影响 size 和 capacity
//设置之后 capacity >= size = 3 
//例:dv={1,2,3,4,5,6}
//运行之后 dv={1,2,3}, 如果尺寸变小,多余的部分截掉
//例:dv={1,2}
//运行之后 dv={1,2,0}, 如果尺寸变大,新空间用 0 代替

dv.resize(3, 2);
//设置 dv 的 size,如果尺寸变大,新空间全部用 2 代替
//例: dv={1,2}
//运行之后 dv={1,2,2}

dv.capacity();
//返回重新分配内存前 dv 可以容纳的字符数,至少比size大

dv.reserve(4);
//设置 dv 的 capacity=4, 只影响 capacity.
//设置之后,capacity=4
//例: dv={1,2,3}, 此时 dv.capacity()=3
//执行之后, dv.capacity()=4

添加元素

insert (插入函数)
dv.insert(dv.begin(), 3);
//在位置之前插入元素 3
//例: dv={1,2}
//运行之后 dv={3,1,2}

dv.insert(dv.begin(), 2, 3);
//在位置之前插入 2 个元素 3
//例: dv={1,2}
//运行之后 dv={3,3,1,2}

dv.insert(dv.begin(), dv1.begin(), dv1.end());
//在位置之前插入 dv1 区间内所有的元素
//例: dv={1,2}, dv1={5,6,7},
//运行之后 dv={5,6,7,1,2}
emplace系列 (插入函数)
dv.emplace(dv.begin(), 3);
//在位置之前插入元素 3, 相当于dv.insert(dv.begin(),3);
//例: dv={1,2,4}
//运行之后 dv={3,1,2,4}

dv.emplace_front(3);
//在头部插入元素 3, 相当于dv.push_front(3); vector 没有这个函数
//例: dv={1,2}
//运行之后 dv={3,1,2}

dv.emplace_back(3);
//在末端插入元素 3, 相当于dv.push_back(3);
//例: dv={1,2}
//运行之后 dv={1,2,3}

emplace系列 / push系列 / insert的区别

  1. 原理上
    emplace系列 是直接将在位置上构造插入的内容, 不需要生成对象
    push系列 / insert是先生成具有复制内容的对象, 然后将对象的内容复制到容器里面
  2. 功能上
    emplace系列 / push系列 只能插入一个元素
    insert 可以插入多个
  3. 性能上
    因为功能比较少, 所以 emplace系列 的速度要更快一点

push系列与insert的区别

  1. 功能上
    push系列只能在头部或末端添加元素
    insert可以在任何地方添加元素
  2. 性能上
    push系列速度更快一点

删除元素

erase (删除函数)
dv.erase(dv.begin());
//删除位置上的元素, 返回迭代器, 指向下一个元素
//例: dv={1,2,3}
//运行之后 dv={2,3}

dv.erase(dv.begin(), dv.end());
//删除区间内的元素
//例: dv={1,2,3}
//运行之后 dv={}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux系统上使用VS Code配置C/C++环境可以提供一个方便的开发环境。以下是配置步骤: 1. 安装VS Code:首先,你需要在Linux系统上安装VS Code。你可以从VS Code官方网站下载适用于Linux的安装包,并按照指示进行安装。 2. 安装C/C++扩展:打开VS Code,点击左侧的扩展图标(四个方块组成的图标),搜索并安装"C/C++"扩展。这个扩展提供了C/C++开发所需的功能和工具。 3. 安装GCC编译器:C/C++代码需要使用GCC编译器进行编译。在终端中运行以下命令安装GCC编译器: ``` sudo apt-get install build-essential ``` 4. 配置任务:在VS Code中,按下Ctrl+Shift+P打开命令面板,输入"Tasks: Configure Task"并选择"Create tasks.json file from template"。然后选择"C++"模板,这将创建一个tasks.json文件。 5. 配置编译任务:编辑tasks.json文件,将以下内容添加到"tasks"数组中: ``` { "label": "build", "type": "shell", "command": "g++", "args": [ "-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}" ], "group": { "kind": "build", "isDefault": true } } ``` 这个配置将使用g++编译器编译当前打开的文件,并将可执行文件保存在与源文件相同的目录中。 6. 配置调试器:在VS Code中,点击左侧的调试图标(类似于虫子的图标),然后点击旁边的齿轮图标,选择"C++ (GDB/LLDB)"。这将在.vscode目录下创建一个launch.json文件。 7. 配置调试任务:编辑launch.json文件,将以下内容添加到"configurations"数组中: ``` { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${fileDirname}/${fileBasenameNoExtension}", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": true, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb" } ``` 这个配置将使用GDB调试器来调试编译后的可执行文件。 8. 开始编写和调试:现在你已经完成了C/C++环境的配置。你可以创建一个新的C/C++文件,编写代码,并使用Ctrl+B进行编译。然后,你可以使用调试功能来运行和调试你的程序。 希望以上步骤对你有帮助!如果你有任何问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值