一:容器
1:vector
构造函数:
vector<int> v1;
vector<std::vector<int>> v2(5, std::vector<int>(6, 2));//二维,5行6列,默认值为2
vector<vector<vector<int>>> v3(5, vector<vector<int>>(4, vector<int>(3)));//三维
方法:
vector<int> v1;
v1.push_back();//加入容器
v1.pop_back();//删除最后一次加进来的元素
v1.size();//容器v1的大小
v1.clear();//清空容器
v1.empty();//容器是否为空,为空==true
v1.resize(5);//重设容器大小
容器遍历:
vector<int> v1;
for (auto &it: v1) {
cout << it << endl;
}
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << endl;
}
2:stack
vector其实也可以当作栈使用,栈只允许访问栈顶。
构造函数:
stack<double> stk;
方法:
stk.push(1.4);//入栈
stk.pop();//出栈
cout << stk.top() << endl;//栈顶元素
cout << stk.size() << endl;//栈大小
stk.empty();//容器是否为空,为空==true
遍历:
栈不支持迭代器遍历。
3:queue
1:普通队列queue
构造函数
queue<int> q1;
方法:
q1.push(3);
q1.front();//队首元素
q1.back();//队尾元素
cout << q1.size() << endl;//队列大小
q1.pop();//出队
q1.empty()//容器是否为空,为空==true
q1.size();//栈大小
遍历:
队列和栈同样不支持迭代器遍历。
2:优先队列priority_queue
优先队列,每次插入取出会保证顺序,只能访问堆顶,元素是常量不可更改(普通队列和栈可以更改)
构造方法:
priority_queue<int, vector<int>, greater<int>> pq;
//默认为大顶堆,最大的数可以取出来,第二个参数为优先队列底层数据存储类型,默认为vector,第三个参数控制大小顶堆
方法:
pq.push(2);//入队
pq.push(5);
pq.push(1);
cout << pq.top() << endl;//队首元素
pq.pop();//出队
遍历:
不支持迭代器遍历。
4:集合set
set | unordered_set | multiset | |
---|---|---|---|
是否有序 | 有序 | 无序 | 有序 |
元素互异 | 互异 | 互异 | 非互异 |
1:set
set中元素互异且有序,可用于元素去重或者维护顺序,不支持下标索引([n])
构造方法:
set<int> st;
方法:
st.insert(12);//插入集合
st.insert(12);
st.insert(13);
st.insert(14);
st.insert(14);
st.erase(14);//删除14元素
//该代码中。set内只有12,13两个元素
st.find(12);//返回指向元素12的迭代器指针
st.clear();//set集合清空
st.empty();//set集合是否为空
遍历:
for(set<int>::iterator it=st.begin();it!=st.end();it++){
cout << *it << endl;
}
for (auto &ele: st) {
cout << ele << endl;
}
for (int it: st) {//现在都用auto了,可以改成auto&或者int
cout << it << endl;
}
2:unordered_set
暂未使用
3:multiset
暂未使用
5:map映射
任意类型到任意类型的映射。
1:map
键不可重复出现,且会按照从小到大排序。
构造方法:
map<string, int> mm;
map<string, vector<int>> mm2;
mm["a"] = 1;
mm["b"] = 2;
cout << mm["as"] << endl;//会默认创建键
方法:
mm.find("a");//返回‘a’键的迭代器索引,若未找到则返回mm.end()
mm.erase("a");//删除键值对
mm.count("b");//查找b键出现了多少次
mm.size();//映射的大小
遍历:
for (map<string, int>::iterator it = mm.begin(); it != mm.end(); it++) {
//map中每一个键值对由pair储存,第一个为键,第二个为值
cout << it->first << "-----" << it->second << endl;
}
for (auto &ele: mm) {
cout << ele.first << "---" << ele.second << endl;
}
2:multimap
键可以重复出现,且会按照从小到大排序。
3:unordered_map
键不可重复出现,且是无序的。
示例:
unordered_map<char, char> mm = {{'(', ')'},
{'[', ']'},
{'{', '}'}};
6:string
构造方法:
string s;
char buf[100];
scanf("%s", buf);
s = buf;
cout << s << endl;
printf("%s\n", s.c_str());
string s2(5, '0');
s2 = "awawa";
string s1(5, '0');
方法:
if (s1 == s2)//判断两个字符串是否相等
s2 + s1;//两个字符串相加
s2.substr(3);//取子串,从下标为3到结尾
s2.substr(3, 1);//取子串,从下标为3,取长度为1
if (s2.find("aw") != string::npos) {
//find找不到会返回string::npos,找到了返回第一个下标,时间复杂度较高,On2
cout << s2.find("wa") << endl;
}
字符串互转
//字符串转其他
long long x = stoll(ss);//
stoi();//转整形
stof();//转float
stod();//转double
stold();//转long double
//其他转字符串
int y = 6666;
string sss = to_string(y);
7:pair二元组
两个元素一个组合
构造方法:
pair<int, int> p = {1, 2};//类似于一个小结构体
pair<int, int> p2 = {1, 2};
pair<char, int> p3 = {'a', 1};
pair<pair<int, char>, int> p4;//不建议使用
方法:
if (p == p2) {//可以直接使用==判断两个元组是否相等
cout << "yes" << endl;
}
二:迭代器
迭代器,对于线性数据结构,下标可以完成。对于非线性的数据结构后,则需要迭代器(一种遍历方式)
例如:
void testIterator() {
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int>::iterator it = v1.begin();
auto it2 = v1.end();
cout << it2 - it << endl;//有些(vector,deque)可以用,有些容器不能用
}
注:栈,队列不可使用迭代器
随机访问迭代器 | 提供读写操作,并能通过跳跃的方式访问(下标)容器内的任意数据 | 读写,支持++,–,[n],-n,<,<=,>,>= |
双向迭代器 | 提供读写操作,并能向前和想和操作 | 读写,支持++,– |
常用容器 | 迭代器 |
---|---|
vector | 随机访问迭代器 |
deque | 随机访问迭代器 |
list | 双向迭代器 |
set | 双向迭代器 |
map | 双向迭代器 |
stack | 不支持 |
queue | 不支持 |
三:算法
1:swap()
交换值
void testSwap() {
string a = "ada";
string b = "bab";
cout << a << " " << b << endl;
swap(a, b);
cout << a << " " << b << endl;
}
2:sort()排序算法
自定义比较器:
bool cmp(pair<int, int> a, pair<int, int> b) {
//第二位从小到大
if (a.second != b.second)
return a.second < b.second;
//第一位从大到小
return a.first > b.first;
}
void testSort() {
vector<int> arr{1, 8, 3, 1, 6, 4, 9, 2};
sort(arr.begin(), arr.end(), greater<int>());//默认从小到大,greater<int>()为自带比较器
for (auto it = arr.begin(); it < arr.end(); ++it) {
cout << *it << " ";
}
//自定义比较器
vector<pair<int, int>> arr2{{1, 9},
{2, 9},
{1, 9},
{0, 0}};
//若a==b,cmp函数一定要返回false,和sort的实现方式有关。否则可能会报错
sort(arr2.begin(), arr2.end(), cmp);
for (auto ele: arr2) {
cout << ele.first << ' ' << ele.second << endl;
}
}
3:二分法查找
查找序列必须保证有序
- lower_bound(begin,end,x):返回不小于查找值x的迭代器位置
- upper_bound(begin,end,x):返回大于查找值x的迭代器位置
void testBound() {
vector<int> arr{0, 1, 1, 1, 8, 9, 9};
//lower_bound返回迭代器,若没有则返回尾迭代器,减去头迭代器返回查找值的下标
int pos = lower_bound(arr.begin() + 1, arr.end(), 1) - arr.begin();
cout << pos << endl;
int pos2 = upper_bound(arr.begin(), arr.end(), 8) - arr.begin();
cout << pos2 - 1 << endl;
}
4:reverse翻转
void testReverse() {
vector<int> arr{0, 1, 1, 1, 8, 9, 9};
reverse(arr.begin(), arr.end());
for (auto ele: arr) {
cout << ele << " ";
}
}
5:最大值Max最小值Min
void testMaxMin() {
cout << max(1, 2) << endl;
cout << min({1, 2, 3}) << endl;
}
6:去重函数Unique
去重函数,删除数组的相邻重复元素,数组长度不变,会在有效元素后填充无效元素,去重前需要先排序。
void testUnique() {
vector<int> arr{5, 1, 8, 6, 6, 4, 8};
sort(arr.begin(), arr.end());
vector<int>::iterator it = unique(arr.begin(), arr.end());//返回要有效数据的后一位的迭代器
arr.erase(it, arr.end());
for (auto ele: arr) {
cout << ele << " ";
}
}
7:数学函数
均支持int/long long /float/double/long double
- abs:绝对值
- exp(2):e的2次方
- log(3):3的自然对数
- pow(2,1/3):2的3分之1次方
- sqrt(2):根号2
- ceil(2.1):向上取整
- floor(2.1):向下取整
- round(2.1):四舍五入
8:最大公因数gcd与最小公倍数lcm
c++17支持直接调用,否则自己编写
int gcd(int a, int b) {
if (!b)
return a;
return gcd(b, a % b);
}
int lcm(int a, int b) {
return a / gcd(a, b) * b;
}
void testGL() {
int x = gcd(8, 12);//4
int y = lcm(8, 12);//24
}