C++知识
指针
*号的两种使用定义指针
int* p, int *p,星号位置不重要解指针
p = &a ,*(p)指针可用
->访问成员变量,ptr->member等价于(*ptr).member也可以连续访问
root->left->right
1 | |
new关键字返回的是指针
所以构造结点的正确做法如下
1 | |
vector 向量(动态数组)
vector<int> vec(n, 1);初始化长度为 n,元素全为 1 的向量vector<vector<int>> vec;空的二维向量int m = matrix.size(), n = matrix[0].size();获取向量的长度 m,每一项的长度为 nvec.push_back({b});添加每一项的第一个vec[i].push_back(b);添加每一项的第二个vec.resize(n);初始化,分配空间之后才能赋值,所有初值为 0swap(nums[i], nums[j]);交换两个元素vec[0], vec.back()返回第一个和最后一个元素的引用vec.begin(), vec.end()返回第一个和最后一个元素的迭代器ranges::reverse(nums.begin(), nums.begin() + k);翻转向量,123->321ranges::sort(vec);排序数组vec.erase(it);动态删除向量里的元素vec1 = move(vec2);把 vec2 内部的指针等资源直接转移给 vec1,vec2 空,时间复杂度 O(1),vec1 会被完全覆盖vec.emplace_back(pair)功能相当于vec.push_back(pair),但在面对复杂对象时效率更高,他是直接在 vec 里面创建这个对象vector vec(n, string(m, '.'));快捷创建 n 行 m 列二维向量
1 | |
二维向量相关操作
1 | |
unordered_map 哈希表
unordered_map<int, int> map;初始化map[i] == map2[i]用操作符[]访问不存在的 key 时会隐式的插入 0 污染 map,即使作为判断条件也是map.count(key)判断是否存在,返回 0 或 1,在上面的判断条件里加上map2.count(s[i]) &&先执行就能避免污染- map 是无序的,用
for (auto& x : map)迭代也是随机的
迭代器
- 实质是一个指针,可用
it -> first, it -> second访问内部成员 - 也可以完全解指针
&a = *it, a -> first - 用于迭代
for (auto it = c.begin(); it != c.end(); ++it)或者for (const auto& x : vec) - 类型复杂所以直接用 auto 声明
- 很多函数返回的都是迭代器,就比如
lower_bound(), map.find(key), nums.begin(), nums.end()
lambda 表达式(匿名函数)
C++在方法内定义方法就要用这种隐函数的语法
函数名只能用 auto[capture](parameters) -> return-type { body }
1 | |
捕获器类型
- [] 不捕获任何外部变量
- [&] 按引用捕获所有用到的外部变量(推荐用于读写或大对象)
- [=] 按值捕获所有用到的外部变量(只读副本)
- [&nums, threshold] 显式按引用捕获 nums,按值捕获 threshold
定义递归函数,把函数自身作为参数传进去(this auto&& dfs)
1 | |
<<>>位运算符
<<运算符用于左移,>>运算符用于右移
1 | |
&运算符用于位与,|运算符用于位或,^运算符用于位异或,~运算符用于位取反
1 | |
deque 双端队列
两侧都能添加和删除元素deque<int> q;初始化pop_front() 删除队列首元素,动态删除,删完之后队首元素索引还是 0pop 访问队首元素,但不删除
条件
C++ 的&&是从左到右求值,所以会先执行q.back(),再判断!q.empty(),在 q 为空的时候这么做会报错
正确做法:while (!q.empty() && nums[i] > nums[q.back()])
字符串
操作和动态数组很像
可以直接加减字符串
string ans = t + 'a'构建子串
std::string sub1 = s.substr(0, 5); // 选取从 0 开始的长度为 5 的子串
std::string sub2 = s.substr(7); // 选取从 7 开始的子串
stack 栈
stack<int> s;初始化s.push(x)入栈s.pop()出栈s.top()访问栈顶元素,要获取栈顶再弹出就要先 top()再 pop()s.empty()判断栈是否为空st = stack<int>();构造空栈,置空栈
单调栈,栈内元素是单调的
1 | |
queue 队列
先进后出,从队尾入队,队首出队(就是排队)
可用于广度优先搜索(BFS)
queue<T> q;初始化q.push(x)入队q.pop()出队q.front()访问队首元素,要获取队首再弹出就要先 front()再 pop()q.empty()判断队列是否为空
Deque 双端队列
构造函数的初始化列表
用初始化列表初始化成员变量,比赋值更高效
const 成员和引用成员只能用初始化列表初始化
- LRUCache(int _capacity) 是构造函数的参数列表;
- :capacity(_capacity),size(0) 为初始化列表
1 | |
结构体
结构体(struct)是一种用户自定义的数据类型,允许将不同类型的数据组合在一起。
结点就是一种定义的结构体,用指针加成员访问符->可以访问成员变量,用结构体名加.也可以访问成员变量
1 | |
pair 二元组
pair 是 C++ 标准库中的一个类,用于存储两个元素。
适合遍历图,Map,表示坐标,键值对
有两个成员变量 first 和 second,分别表示键和值。
vector<pair<int, int>> q;坐标向量for (auto& [x, y] : q)结构化绑定遍历
或者for (auto& p : q)然后用 p.first, p.second 访问
Map 哈希表
map 里面的元素是键值对,pair 来表示,也可称作 entry
first 和 second 是 pair 的成员变量
map 的遍历for (auto& [key, value] : map)for (auto& p : map)然后用 p.first, p.second 访问`