STL容器、位运算与常用库函数 所有题目来自ACWing 点这注册AcWing 邀请码:SMDRN
👇从零开始学C++系列👇
从零开始学C++之基本知识 从零开始学C++之数组和字符串 从零开始学C++之函数、结构体、类、指针、引用 从零开始学C++之STL容器、位运算与常用库函数
STL容器
vector
在数组末尾插入删除O(1) ,在开头插入删除O ( n )
定义
??向量(Vector)是一个封装了动态大小数组的顺序容器。跟任意其它类型容器一样,它能够存放各种类型的对象。 ??可以简单的认为,向量是一个能够存放任意类型的动态数组
特性
- 顺序序列
顺序容器中的元素按照严格的线性顺序排序。可以通过元素在序列中的位置访问对应的元素。 - 动态数组
支持对序列中的任意元素进行快速直接访问,甚至可以通过指针算述进行该操作。提供了在序列末尾相对快速地添加/删除元素的操作。 - 能够感知内存分配器的
容器使用一个内存分配器对象来动态地处理它的存储需求
代码
定义
- Vector<类型>标识符
- Vector<类型>标识符(最大容量)
- Vector<类型>标识符(最大容量,初始所有值)
- Int i[5]={1,2,3,4,5}
Vector<类型>vi(I,i+2);//得到i索引值为3以后的值 5.0 Vector< vector< int> >v; 二维向量(这里最外的<>要有空格。否则在比较旧的编译器下无法通过)
#include <vector>
vector<int> a;
vector<int> a[N];
vector<int> a({1, 2, 3});
操作
a[k];
a.size();
a.empty();
a.clear();
a.front();
a.back();
a.push_back(x);
int x = a.pop_back();
int* p = lower_bound(a, a + a.size(), x);
int* p = upper_bound(a, a + a.size(), x);
int index = lower_bound(a, a + a.size(), x); - a;
int index = upper_bound(a, a + a.size(), x); - a;
for (int i = 0; i < a.size(); i++) {...}
for (vector<int>::iterator i = a.begin(); i < a.end(); i++) {...}
for (auto i = a.begin(); i < a.end(); i++) {...}
for (int x : a) {...}
注意:
a.begin() 返回的是vector第1个元素的地址,而a.end() 返回的是最后一个元素的下一个位置的地址
队列(queue)
定义
队列: ??队列就是允许在一端进行插入,在另一端进行删除的线性表。允许插入的一端称为队尾,通常用一个队尾指针r 指向队尾元素,即r 总是指向最后被插入的元素;允许删除的一端称为队首,通常也用一个队首指针f指向排头元素的前面。初始时f=r=0
优先队列: ??priority_queue为优先队列,一般用来解决一些贪心问题,其底层是用“堆”来实现的。在优先队列中,任何时刻,队首元素一定是当前队列中优先级最高(优先值最大)的那一个(大根堆),也可以是最小的那一个(小根堆)。可以不断往优先队列中添加某个优先级的元素,也可以不断弹出优先级最高的那个元素,每次操作其会自动调整结构,始终保证队首元素的优先级最高
先进先出特性
可参考之前的文章 C++学习之队列&&优先队列
代码
队列:
#include <queue>
queue<int>vis;
vis.push(x);
int x = vis.pop();
vis.front();
vis.back();
vis = queue<int>();
优先队列
#include <queue>
priority_queue<int> a;
priority_queue<int, vector<int>, less<int>> a;
priority_queue<int, vector<int>, greater<int>> b;
priority_queue<type> name;
struct Rec {
int a, b;
bool operator< (const Rec& t) const {
return a < t.a;
}
bool operator> (const Rec& t) const {
return a > t.a;
}
}
priority_queue<Rec> a;
priority_queue<Rec, vector<Rec>, greater<Rec>> b;
操作: ??和queue不一样的是,priority_queue没有front() 和back() ,而只能通过top() 或pop() 访问队首元素(也称堆顶元素),也就是优先级最高的元素。
q.empty()
q.size()
q.top()
q.pop()
q.push(x)
注意:除了队列、优先队列、栈之外,其他所有STL容器均有clear()函数
栈(Stack)
顾名思义:先进后出
#include <stack>
stack<int> s;
s.push(x);
s.top();
s.pop();
双端队列(deque)
扩展版vector deque在数组开头/结尾插入删除都是O(1)的
#include <deque>
deque<int> q;
q[i]
q.begin();
q.end();
q.front();
q.back();
q.clear();
push_back(x);
push_front(x);
pop_back();
pop_front();
set
有序 特点:元素不能重复
#include <set>
set<int> s;
multiset<int> ms;
s.size();
s.empty();
s.claer();
s.begin();
s.end();
s.insert(x);
s.find(x);
s.lower_bound(x);
s.upper_bound(x);
s.erase(x);
s.count(x);
重载 小于符合
struct Rec
{
int x, y;
bool operator< (const Rec& t) const
{
return x < t.x;
}
};
set<int> Rec;
find()、erase()、lower_bound()和upper_bound() 都是O(logn) 复杂度 count() 是O(k+logn) 复杂度
unordered_set
无序set 底层实现哈希表
#include <unordered_set>
unordered_set<int> s;
unordered_multiset<int> s;
bitset
位运算 很长的二进制01串
#include <bitset>
bitset s;
s.count();
s.set(p);
s.reset(p);
bitset 元素支持位运算符& 、| 和~ 等等- 求
x 的第k 位二进制数:x >> k & 1 - 求
x 从右起的第1个1:lowbit(x) = x & -x ; 实际上是原码和补码做与操作 例如110110返回10,11000返回1000
pair
有序对 将两个数据变为一个数据
template<class T1,class T2> struct pair
pair<int, int> a = {5, 6};
pair<int, int> b = make_pair(5, 6);
pair<int, string> a;
a = {3, "test"};
a = make_pair(4, "check");
a.first() 和a.second() 分别输出第一个和第二个值
map
有序对
#include <map>
map<string, int> m;
a["a"] = 4;
m.insert();
m.find();
algorithm库
头文件 #include <algorithm>
reverse 翻转
// 翻转 数组反转 reverse(a.begin(), a.end()); reverse(a, a + a.size());
unique 去重
??返回去重之后的尾迭代器(或指针),仍然为前闭后开,即这个迭代器是去重之后末尾元素的下一个位置。该函数常用于离散化,利用迭代器(或指针)的减法,可计算出去重后的元素个数
unique(a, a + a.size()); 返回去重后最后一个元素的地址
int m = unique(a, a + a.size()) - a; 去重后数组的长度 a.erase(unique(a.begin(), a.end()), a.end()); 真删除重复元素
random 随机打乱
// 随机打乱 用法与reverse相同 random_shuffle(a.begin(), a.end());
sort 排序
sort(a.begin(), a.end());
sort(a.begin(), a.end(), greater<int>());
bool cmp(int a, int b) {return a - b;}
sort(a.begin(), a.end(), cmp);
二分
在有序的容器里 lower_bound 返回大于等于x位置的迭代器 upper_bound 查找第一个大于x
例如: 在有序int数组(元素存放在下标1~n)中查找大于等于x的最小整数的下标: int I = lower_bound(a + 1, a + 1 + n,. x) – a;
题目
75. 和为S的两个数字 51. 数字排列
|