-
常用头文件
-
iostream
:cin, cout, scanf, printf
-
cstdin
:scanf, printf
cmath
-
bits/stdc++.h
: 万能头文件,但引用时间稍长
-
-
swap()
: 新编译器中,swap
包含在iostream
中,调用swap(int x,int y)
即可;在旧编译器中,需要使用algorithm库 -
逗号运算符:C++的,运算符对逗号前后的表达式进行运算,然后舍弃前一个表达式的返回值,仅仅返回最后一个表达式的返回值
if(cin >> a >> b, a > 0, b > 0); // if只看最后一个表达式b>0,不关心cin和a>0
-
处理T组数据
int T = 0; cin >> T; while(T--){ // 处理过程 } return 0;
-
char数组问题
char a[] = {'C', '+', '+'}; char b[4] = {'D', '+', '+', '\0'}; char c[5] = {'E', '+', '+', '\0'}; // 最后一个位置会补\0 cout << a << endl; // 输出"C++D++",因为字符数组a不会自动添加'\0',cout会读取到b的部分
-
cstring
:?memset(array, value, end)
-
0x3f3f3f
比较大的值int h[100]; memset(h, 0x3f, sizeof h); // memset按照字节初始化, h为int类型,int有四个字节,每个字节初始化为0x3f即可。
输入
-
scanf("%d%d", &a, &b);
-
cin >> a >> b;
-
字符的读入
scanf("%c%c", &a, &b); cin >> a >> b;
-
cin, cout
输入输出加速代码cin.tie(0); ios::sync_with_stdio(0);
Tips: 加速代码仅针对
cin, cout
,添加加速代码后,cin, cout
不能与scanf, printf
混用。
输出
printf("%d%d", a, b);
cout << a << b;
puts()
基本模板
#include <iostream>
using namespace std;
int main()
{
int a = 0, b = 0;
cin >> a >> b;
cout << a + b << endl;
return 0;
}
STL
vector
变长数组
vector<int> q(length, value); // 指定数组长度为length,指定默认值为value。
push_back() // 插入
size() // 查看元素个数,O(1)
clear() // 清空
empty() // 是否为空
front() / back() // 返回数组第一个 / 最后一个 元素
push_back() // 从后面添加一个数
pop_back() // 弹出最后一个元素
begin() / end() // 迭代器:第0个元素的位置 和 最后一个元素后一个位置
[] // 支持随机选址
// 支持字典序比较
#include <vector>
// 定义
vector<int> a; // 一维数组
vector<int> b[N]; // 二维数组
// 初始化
vector<int> a({1, 2, 3});
// 操作
a[k]; // 取值
a.size(); // 长度
a.empty(); // 判空
a.clear(); // 清空
a.front(); // 读取第1个元素
a.back(); // 读取最后1个元素
a.push_back(x); // 在末尾插入元素
int x = a.pop_back(); // 删除末尾元素并返回
int* p = lower_bound(a, a + a.size(), x); // 查找数组在指定范围内大于等于x的元素地址(要求数组有序)
int* p = upper_bound(a, a + a.size(), x); // 查找数组在指定范围内大于x的元素地址(要求数组有序)
int index = lower_bound(a, a + a.size(), x); - a; // 查找数组在指定范围内大于等于x的元素下标(要求数组有序)
int index = upper_bound(a, a + a.size(), x); - a; // 查找数组在指定范围内大于x的元素下标(要求数组有序)
// 遍历
for (int i = 0; i < a.size(); i++) {...} // 方式1,通过a[i]读取元素值
for (vector<int>::iterator i = a.begin(); i < a.end(); i++) { // 方式2(迭代器),通过*i读取元素值
cout << *i << " ";
}
for (auto i = a.begin(); i < a.end(); i++) {cout << *i << " ";} // 方式3(迭代器简化版)
for (auto x : a) {...} // 方式4,通过x读取元素值
// 字典序比较
vector<int> a(4, 3), b(3, 4);
if(a < b) puts("a < b");
// output : "a < b"
a.begin()
返回的是vector第1个元素的地址,而a.end()
返回的是最后一个元素的下一个位置的地址,取值需要加上*
stack
栈
stack<int> stk;//定义
stk.push(1);//从栈顶插入
stk.top();//返回栈顶元素
stk.pop();//从栈顶弹出
stk.empty();//是否为空
queue
队列
queue<int> q;//定义一个队列q
q.push(1);//像队尾插入1
q.pop();//弹出队头
q.empty();//返回队列是否为空
q.front();//返回队头元素
q.back();//返回队尾元素
q = queue<int>();//已定义q时,重新定义一个队列。
deque
双端队列,加强版vector
,支持双端添加、弹出元素。效率较低
deque<int> dq;//定义一个双端队列
deque.size();//返回长度
//插入
dq.push_front(1);//向队头插入
dq.push_back(1);//向队尾插入
//删除
dq.pop_front();//删除队头
dq.pop_back();//删除队尾
//访问
dq.front();//访问第一个元素
dq.back();//访问最后一个元素
cout << dq[0] << endl;//下标访问
dq.begin();//开头指针迭代器
dq.end();//末尾指针迭代器
dq.clear();//清空
dq.empty();//是否为空
priority_queue
优先队列,可理解为堆。
push() //插入一个元素
top() //返回堆顶元素
pop() //弹出堆顶元素
empty() //判断堆是否为空
size() //返回元素个数
Tips: 默认定义为大根堆,可以采用插入-x
的方式实现小根堆的效果,也可以直接定义小根堆。
// 头文件
#include<queue>
#include<vector>
// 定义
priority_queue<int> heapone;// 定义大根堆
priority_queue<int, vector<int>, greater<int>> heaptwo;//定义小根堆
// 操作
heaptwo.top();//返回堆顶元素
heaptwo.push(1);//向堆插入一个数。
heaptwo.pop();//弹出堆顶元素
heaptwo.empty();//判断堆是否为空
heaptwo.size();//返回元素个数
string
字符串
string line;//定义字符串
getline(cin, line);//读入字符串方式1
cin >> line;//读入字符串方式2
//推荐cin读入字符串
line[1];//访问元素
line.substr(x, length);//取出从x开始的长度为length的子串 length = min(length, line.size())
line.substr(1); //返回从1开始的整个子串
line.size();//返回元素个数
line.length();//和size相同
line.empty();//判断是否为空
ling.clear();//清空
line.push_back();//插入字符
-
输入
#include <string> string str; cin >> str; // 不能读取含空格、换行符的字符串 getline(cin, str); // 能读取含空格的字符串,同时自动去掉换行符\n
-
操作
string str; string s(5, 'a'); // 构造重复字符的字符串 str.empty(); // 判空 str.clear(); // 清空 str.size(); // 长度,与stelen()不同的是,这个复杂度是O(1),不用额外的变量保存 str.c_str(); // 转成char数组,此时才可用printf输出 str.substr(begin, length); // 子串 str.pop_back(); // 删除最后一个字符 // 字符串比较">"、"<" // 字符串拼接"+" for (char ch : str) {...} // 遍历(不可修改字符) for (char &ch : str) {...} // 遍历(可修改字符)
-
字符串流*
#include <sstream> string s; stringstream ssin(s); while(ssin >> s) {...} // 按空格拆分s,例如英语句子拆分单词 // 可用如下代码代替 while(cin >> word) { ... }
pair
组合数据结构,排序时默认按元素结构顺序排序,可以嵌套。
-
first
: 第一个元素 -
second
: 第二个元素 - 支持字典序比较:以
first
为第一关键字,以second
为第二关键字(字典序)
pair<int, string> tone;//定义二元组
pair<int, pair<int, string>> ttwo;//定义三元组
pair<int, int> tthree[10086];//定义pair数组
cout << tone.first << endl;//查看tone的第1项。
cout << tone.second << endl;//查看tone的第二项
cout << ttwo.second.second << endl;//循环嵌套
// 构造一个pair
p = make_pair(10, 'ss');
p = {10, 'ss'}; //c++11 特性
map
字典,内容为'key':value
形式
#include <map>
map<int, string> Map;//定义一个以int为索引,拥有指向string的指针。
pair<int, string> in = {000, "cht"};
//插入元素
Map.insert(in); //插入一个pair
Map[1] = 'hello'; //像数组一样访问,时间复杂度O(logn)
Map.find(000);//返回元素位置
Map.erase(000);//删除元素(至此cht被踢出了Map),参数是pair或者迭代器
Map.size();//返回大小
Map.begin();//头部迭代器
Map.end();//尾部迭代器
Map.clear();//清空
Map.count();//返回元素个数
Map.empty();//返回map是否为空
Map[0];//下标访问
lower_bound(); //返回 大于等于x 的 最小的数,不存在则返回end()迭代器
upper_bound(); //返回 大于x 的 最小的数,不存在则返回end()迭代器
set
multiset / set
-
set
: 集合,存储无重复元素,操作时间复杂度nlogn
。 -
multiset
: 集合,可存储重复元素。
set<int> S;
S.begin();//返回第一个元素的地址
S.end();//返回最后一个元素的地址
S.clear();//清空
S.empty();//是否为空
S.size();//返回长度
S.count(1);//返回1的个数
S.find(1);//寻找,不存在则返回end()迭代器
S.erase(1);//删除
/*
a. 输入是一个数x,则删除所有x。
b. 输入是一个迭代器,删除这个迭代器。
*/
S.insert(1);//插入
// 核心操作
lower_bound(); //返回 大于等于x 的 最小的数,不存在则返回end()迭代器
upper_bound(); //返回 大于x 的 最小的数,不存在则返回end()迭代器
list
相当于双向链表。
#include<list>
// 具体操作
list<int> L;
L.push_back(1);//插入
L.empty();//判断是否为空
L.begin();//返回头结点
L.end();//返回尾部节点
L.insert(L.begin(), 1);//在指定位置插入
L.erase(L.begin());//删除
L.erase(L.begin(), L.end());//区间删除
L.clear();//清空list
L.push_front();//插入
L.pop_front();//删除
L.pop_back();//删除
L.size();//元素个数
unordered_
unordered_set, unordered_map, unordered_multiset, unordered_multimap
哈希表
基础操作类似于set, map
,但增删改查的时间复杂度为0(1)
不支持lower_bound() / upper_bound()
bitset
压位,节省空间。
bitset<10000> s; // 声明一个10000位的bitset
// 支持与或运算 ~, &, |, ^
// 支持移位操作 >>, <<
// 支持比较操作 ==, !=
// 支持随机读取 []
count(); // 返回有多少个1
any(); // 判断是否至少有一个1
none(); // 判断是否全为0
set(); // 把所有位都置为1
set(k, v); // 将第k位变成v
reset(); // 把所有位置变成0
flip(); // 等价于~
flip(k); // 把第k位取反
其他
Algorithm库
#include <algorithm>
vector<int> a;
// 翻转
reverse(a.begin(), a.end());
reverse(a, a + a.size());
// 去重
unique(a, a + a.size()); // 返回去重后最后一个元素的地址
int m = unique(a, a + a.size()) - a; // 去重后数组的长度
a.erase(unique(a.begin(), a.end()), a.end()); // 真删除重复元素
// 打乱
random_shuffle(a.begin(), a.end());
// 排序
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); // 自定义排序
参考