C++ STL容器
根据 bilibili黑马程序员视频 网上资料 自己理解 整理的部分资料C++语法
1. STL 常用容器
面向对象的三大特性:封装、继承和多态。
- 基本内容
STL:Standard Template Library,标准模板库,包括容器、算法和迭代器,容器和算法通过迭代器进行无缝衔接。
STL的六大组件:容器、算法、迭代器、仿函数、适配器、空间配置器
容器可以分为序列式容器和关联式容器,其中序列式 元素固定的位置,而关联式 元素排序好 但没有物理上的顺序
算法需要通过迭代器才能访问容器中的元素,迭代器类似于指针。
常用的容器中的迭代器为双向迭代器 和 随机访问迭代器
2. vector容器
vector
容器类似于 数组,也称为单端数组,使用迭代器 vector<int>::iterator
,内置遍历算法for_each
。
区别:数组是静态空间,vector 动态扩展空间,将原数据拷贝到新空间并释放原空间
可以存放自定义数据类型,指针p(地址)通过p->成员
或 解引用 指针 用(*p).成员
取元素
常用语法:
构造:vector<int> v1; vector<int> v2(v1); //拷贝构造
赋值:v2 = v1;
等价于 v2 = v1.assign(v1.begin(), v1.end());
容量判断:empty(); //判断容器是否为空
,size(); //返回容器中元素的个数
插入和删除:v.push_back(ele); //尾部插入元素ele
,v.pop_back(); //删除最后一个元素
,v.capacity() 返回容量
,v.resize() 重新指定大小
互换容器:实现两个容器内元素互换,v2 = swap(v1); // 交换v1 v2的元素
,用于收缩内存(通过匿名对象,匿名对象执行完成后自动销毁)
#include<vector> // 包含头文件vector
#include<algorithm> // 使用内置遍历算法,需要包含头文件 algorithm
vector<int > v;
int p = 10;
v.push_back(p); // 尾部插入元素
v.pop_back(); //删除最后一个元素
v.begin(); // 指向第一个元素
v.end(); // 指向最后一个元素的下一个位置
v.empty(); //判断容器v是否为空
v.size(); //返回容器v中元素的个数
v.insert(pos, elem); // 向 迭代器 指定位置pos 插入元素elem
v.erase(pos); // 删除 迭代器 指定位置pos 的元素elem
v.clear(); // 清空容器v中所有元素
v.front(); // 返回容器v中 第一个元素
v.back(); // 返回容器v中 最后一个元素
v[i]; // 访问 v 中 第i个元素
v.at(i); // 访问 v 中 第i个元素
vecotr<vector<int >> v2; // 嵌套vector的vector容器
v2 = swap(v1); // 交换v1 v2的元素
vector<int>(v).swap(v); // 通过匿名对象vector<int>(v) 实现收缩内存
v.reserve(); // 预留分配空间,并且没有初始化 不能访问;减少在动态扩展容量时的扩展次数
sort(v.begin(), v.end()); // 内部排序方式
- string容器
string本质是一个类,类内部封装了char *
指针,是一个char *
型容器
常用语法:
幅值操作:常用 string s = "Hello";
等价于 string str; str.assign("Hello");
字符串拼接:s1 += s2;
等价于 s1.append(s2);
查找:find
从左到右,rfind
从右到左,返回查找的第一个字符的位置,找不到返回 -1
替换:replace 替换时,要指定起始位置 字符个数 以及 替换成的字符串
比较:按照字符串的ASCII码比较,主要用于判断两个字符串是否相等 int res = s1.compare(s2);
存取:通过[ ]
或 at
访问字符串中的单个字符 s1[1] = 'c';
或 s1.at(1) = 'c';
插入:s1.insert(1,"111");
删除:s1.erase(1,3);
子串:string s2 = s1.substr(1,3);
#include<string>
string s1; // 创建空字符串 s1
string s2 = "hello world"; // 字符串 s2 的初始化
string s3(s2); //调用拷贝构造函数
string s1 = "Hello"; s1 += "world"; // 字符串末尾拼接 1. +=
string s2 = "Hello"; s1.append("world"); // 字符串末尾拼接 1. s1.append(s2);
string s1 = "Hello"; int pos = s1.find("o"); // 字符串查找 s1.find("s2")
string s2 = "abcdefgde"; s2.replace(1, 3, "1111"); // 字符串替换 s2的1号位置(b)起 3个字符 替换为 "1111"
int res = s1.compare(s2); // 字符串比较 比较两个字符串是否相等
s1[1] = 'c'; // 字符串修改 []方式 s1的第一个字符替换为 'c'
s1.at(1) = 'c'; // 字符串修改 at方式
s1.insert(1,"111"); // 字符串插入 从1号位置开始 插入3个字符
s1.erase(1,3); // 字符串删除 从1号位置开始 删除3个字符
string s2 = s1.substr(1,3); // 字符串子串 从1号位置开始 截取3个字符组成字符串 幅值给s2
- deque容器
deque容器 双端容器,可以对头部进行插入和删除
赋值、容量、插入删除、存取与vector容器几乎一样 区别在于,头部也可以插入和删除 用front
即可
deque排序:sort算法非常实用,使用时包含头文件 algorithm
#include<deque>
deque<int> d; // deque构造
deque<int> d1(d); // 拷贝构造函数
d.push_front(); //头插
d.pop_front(); // 头删
sort(d.begin(), d.end()); // 自动排序,默认从小到大
- stack容器
栈容器:入栈push()
,出栈pop()
,按照先进后出FILO
,并且不能遍历
#include<stack>
stack<int> st;
st.push(10); // 入栈
st.pop(); // 出栈,弹出
st.top(); // 查看 栈顶元素
st.size(); // 返回 栈的大小
- queue容器
队列容器:先进先出FIFO
,入队push()
,出队pop()
,只有队头和队尾能被外界访问,不允许遍历
#include<queue>
queue<int> q;
q.push(10); // 入队
q.pop(); // 出队
q.empty(); // 判断队列是否为空
q.size(); // 返回 队列的大小
q.front(); // 查看 队头元素
q.back(); // 查看 队尾元素
- list 容器
链表:由一系列 结点 组成,结点由 数据域 和 指针域 组成,使用双向迭代器,不支持随机访问,并且不可以通过[]
,at()
访问数据
反转:L.reverse();
,排序L.sort();
不支持随机访问的容器,不能使用全局函数
#include<list>
list<int> L,L1;
L.push_back(10); // 链表 赋值
L1.assign(L.begin(), L.end());
L.push_front(20); // 头插
L.pop_back(); // 尾删
L.insert(pos, elem); // 在pos位置插elem元素的拷贝,返回新数据的位置
L.erase(pos);//删除pos位置的数据,返回下一个数据的位置
L.remove(elem);//删除容器中所有与elem值匹配的元素
L.front(); // 返回 第一个元素
L.back(); // 返回 最后一个元素
L.reverse(); // 反转链表
L.sort(); // 链表排序,默认升序
bool compare(数据类型 &p1, 数据类型 &p2) {
return p1.成员 > p2.成员 // 降序排列
}
- set 容器
集合容器属于关联式容器 通过二叉树实现,其中set
不允许有重复元素,multiset
允许重复元素;
特点:元素插入时,自动排序,利用仿函数可以指定set容器的排序规则
#include<set>
set<int> s1;
s1.insert(10); // set 插入元素只能用 inset()
set<int> s(s1); // 拷贝构造
s.size(); // s 的 大小
s.empty(); // s 是否为空
s1.swap(s); // s1 与 s交换两个集合容器
s.clear(); // /清除所有元素
s.erase(elem); // 删除元素 elem
s.erase(s.begin()); // 删除最小的元素
s.find(key); // 查找key是否存在,返回元素的位置,否则返回s.end()
s.count(key); // 统计元素 key 的个数,对于set要么0,要么1
pair<string, int> p = make_pair("Tom", 20); // 成对出现的数据,利用对组
- map 容器
map 容器中元素均为pair值,第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
不允许有重复的key值,利用仿函数可以指定map容器的排序规则
#include<map>
map<int, int> m;
m.insert(pair<int, int>(1, 10)); // 第一种方式 插入元素
m.insert(make_pair(1, 10)); // 第二种方式 插入元素
m[i] = elem; // 第三种方式 插入元素,[]通过key访问value
m.size(); // 返回容器中元素的数目
m.empty(); // 判断容器 是否为空
map<int, int> m1, m2;
m1.swap(m2); // 交换两个集合容器
m.erase(key); // 按照 key 删除
m.clear(); // 清除所有元素
m.find(key); // 查找 键值为key的元素 有返回pos,否则返回m.end()
m.count(key); // map中不允许插入重复的key,对于map count的结果要么0 要么1