文章目录
1 二元组:pair
pair<int, string> p, p1, p2;
p.first // 第一个元素(int)
p.second // 第二个元素(string)
p1 = make_pair(1, "2"); // 构造pair
p2 = {3, "4"}; // 构造pair(c++11)
// 支持比较运算,先按first排,再按second排
p1 < p2
pair<int, pair<int, int>> pp; // 三元组
2 变长数组:vector
采用倍增的思想,当元素个数超过大小时,将大小*2。
例如分配
1
0
3
10^3
103空间
那么第一次分配空间大小为:1
第二次分配空间大小为:2
第三次分配空间大小为:4
第四次分配空间大小为:8
…
第10次分配空间大小为:512
总共大小:
1
+
2
+
4
+
.
.
.
+
512
=
1023
1 + 2 + 4 + ... + 512=1023
1+2+4+...+512=1023
#include <iostream>
using namespace std;
#include <vector>
int main(){
vector<int> a; // 定义一个vector
vector<int> a(10); // 长度为10的vector
vector<int> a[10]; //同上
vector<int> a(10, 3); // 长度为10的vector,且每个数都是3
//二维vector,大小是[10][100],初始化全为-0x3f3f3f3f
vector< vector<int> > a(10, vector<int>(100, -0x3f3f3f3f));
// 遍历vector(其他set、map也可用)
for (auto x : a) cout << x << endl; // (c++11才可用auto)
for (vector<int>::iterator i = a.begin(); i != a.end(); i ++ ) cout << *i << endl;
for (int i = 0; i < a.size(); i ++ ) cout << a[i] << endl; // 用[]是vector特有的
a.size(); // 返回元素个数 时间O(1)
a.empty(); // a为空返回true 时间O(1)
a.clear(); // 清空a
a.front(); // 返回a第一个数
a.back(); // 返回a最后一个数
a.push_back(1); // 向a末尾插入1
a.pop_back(); // 删除a末尾的数
// 支持比较,按字典序比较,3333 < 444
vector<int> b(4, 3); // 4个3
vector<int> c(3, 4); // 3个4
if (b < c) printf("b < c");
}
3 字符串:string
string a = "abc"; // 创建字符串
a += "def"; // 末尾添加字符串
a.size(); // 返回元素个数 时间O(1),也可用a.length()
a.empty(); // a为空返回true 时间O(1)
a.clear(); // 清空a
a.substr(1, 2); // 从下标1开始,长度为2的子串:bc
a.substr(1, 200); // 超过长度则会输出到最后一个字母:bcdef
a.substr(1); // 输出到最后一个字母:bcdef
printf("%s\n", a.c_str()); // c_str()返回a的起始地址
4 队列:
4.1 queue 普通队列
#include <queue>
queue<int> a;
a.size(); // 返回元素个数 时间O(1)
a.empty(); // a为空返回true 时间O(1)
a = queue<int>(); // 队列没有clear,构造新的来清空
a.front(); // 返回队头
a.back(); // 返回队尾
a.push(1); // 向队头插入
a.pop(); // 队尾弹出
4.2 priority_queue 优先队列
用堆实现
#include <queue>
priority_queue <int> a; // 默认大根堆
// 插入x时改成-x,可变成小根堆
priority_queue <int, vector<int>, greater<int>> b; // 定义小根堆
a.size(); // 返回元素个数 时间O(1)
a.empty(); // a为空返回true 时间O(1)
a = priority_queue <int>() // 队列没有clear,构造新的来清空
a.top(); // 返回堆顶
a.push(1); // 向堆插入
a.pop(); // 弹出堆顶
4.3 deque 双端队列
功能强大但效率很低
#include <deque>
deque<int> a;
a.size(); // 返回元素个数 时间O(1)
a.empty(); // a为空返回true 时间O(1)
a.clear() // 清空a
a.front() // 返回第一个元素
a.back(); // 返回最后一个元素
a.push_back(1) // 队尾插入元素
a.pop_back() // 队尾删除元素
a.push_front(1); // 队首插入元素
a.pop_front(); // 队首删除元素
a[1]; //支持[]取元素
a.begin();
a.end();
5 栈:stack
#include <stack>
stack <int> a;
a.size(); // 返回元素个数 时间O(1)
a.empty(); // a为空返回true 时间O(1)
a = stack<int>() // 栈没有clear,构造新的来清空
a.top(); // 返回栈顶
a.push(1); // 栈顶插入
a.pop(); // 栈顶弹出
6 红黑树(平衡二叉树):
6.1 set
不能有重复元素,插入重复元素将忽略
#include <set>
set<int> a;
a.size(); // 返回元素个数,时间O(1)
a.empty(); // a为空返回true,时间O(1)
a.clear(); // 清空a
a.insert(1); // 插入一个数,时间O(log(n))
a.find(1); // 查找一个数,不存在返回a.end()
a.count(1); // 返回某个数的个数
a.erase(1); // 删除所有等于1的结点,时间O(k + logn)
a.erase(迭代器); // 删除迭代器
a.lower_bound(x); // 返回>=x的第一个数的迭代器
a.upper_bound(x); // 返回>x的第一个数的迭代器
set<int>::iterator it;
it = a.lower_bound(9);
cout << *it << endl;
6.2 map
#include <map>
map<string, int> a;
a.size(); // 返回元素个数,时间O(1)
a.empty(); // a为空返回true,时间O(1)
a.clear(); // 清空a
a.insert({"a", 1}); // 插入一个pair,时间O(log(n)),重复会忽略
a["b"] = 2; // 支持[]来插入元素,时间O(log(n)),重复会覆盖
if(a["b"] == 2); // 支持[]来通过key找value,时间O(log(n))
map<string, int>::iterator it;
it = a.find("a"); // 查找一个pair,不存在返回a.end(),存在返回pair{"a", 1}的地址
cout << it->first << " " << (*it).second << endl; // 输出a 1
a.count("a"); // 返回key="a"的个数
a.erase("a"); // 删除所有key="a"的结点,时间O(k + logn)
a.erase(迭代器); // 删除迭代器 例如a.erase(a.begin())删除第一个
a.lower_bound("a"); // 返回key>="a"的第一个数的迭代器
a.upper_bound("a"); // 返回key>"a"的第一个数的迭代器
it = a.lower_bound("a");
cout << it->first << endl;
6.3 multiset
可以用重复元素
其他操作同set
6.4 multimap
可以用重复元素
其他操作同map
7 哈希表:
和上面操作一样,但增删改查时间是O(1)
不支持lower_bound()和upper_bound()
不支持迭代器的++、–
7.1 unordered_set
7.2 unordered_map
7.3 unordered_multiset
7.4 unordered_multimap
8 压位:bitset
bool flag[1024];需要1024字节
如果压到位里,因为每位是8位,只需要128字节。
#include <bitset>
bitset<10000> a; // 大小10000的bitset
// 支持以下操作
~, &, |, ^
>>, <<
==, !=
[]
a.count(); // 返回多少个1
a.any(); // 判断是否至少有1个1
a.none(); // 判断是否全为0
a.set(); // 把所有变成1
a.set(k, v); // 第k位变成v
a.reset(); // 所有变成0
a.flip(); // 所有位取反
a.flip(k); // 第k位取反