Summary1.2 数据结构 STL整合
[TOC]
数据结构 STL 用法整合
linklist
链表
#include <list>
list<int> linklist;
int main() {
// 往链表头部插入元素
linklist.push_front(2); // 2
linklist.push_front(1); // 1 2
// 往链表尾部插入元素
linklist.push_back(3); // 1 2 3
// 链表排序
linklist.sort();
// 链表去重
linklist.unique();
// 链表长度
int linklistlen = linklist.size();
}
map
功能:映射。
性质:有序性=>根据key有序排列,唯一性=>根据key唯一。
// 功能描述 => 查找出现单次的,并尽可能的节省空间
#include <map>
map<int, bool> m;
// map两种遍历方式
// map利用迭代器进行遍历,需要设置迭代器并且指向对应的map
map<int, bool>::iterator iter = m.begin();
// 或者通过auto来声明:
auto iter2 = m.begin();
while(iter != m.end()) {
cout<<"key = "<<iter->first<<" value = "<<iter->second<<endl;
iter++;
}
// map遍历利用最新的C++17的写法进行遍历,C++11/13/15都是不支持的
for (auto [k, v]: m) cout<<"key = "<<k<<" value = "<<v<<endl;
// map边遍历边移除
for (1~n) {
cin>>t;
if (m.count(t)) m.erase(t); // m.count(t) 返回0或1,数出现次数,map只允许一个key出现一次,所以只有0或1 m.erase(t)移除掉t的key所对应的那个项
else m[t] = true;
}
// 迭代器的移动 => 迭代器只能进行自增操作,也即只能进行 iter++或者iter--,无法进行其他操作
if (iter->first > (--iter)->first) {printf("当前迭代器的key比他前面的迭代器的key的值要大");}
set
功能:集合,内部关联(没有value的map),元素在具体位置
性质:唯一性,有序性。
#include <set>
set<int> s;
s.insert(1);
s.insert(4);
s.insert(2);
s.insert(1);
for (int i: s) printf("%d ", i); // 1 2 4 首先会有序,其次会把重复的删掉
unique 与 离散化
int a[10]和b[10] = {7,1,1,90,1,4,4,4,5,1}, n = 10; // 数据
// 去重
int newn = unique(a, a+n)-a; // 利用unique去重,返回的值是去重之后的数组的长度
for (int i = 0; i < newn; ++i) printf("%d ", a[i]); // 7 1 90 1 4 5 1
// 区间语法
// 0~n-1 => n => sort(a, a+n), unique(a, a+n)-a
// 1~n => n => sort(a+1, a+n+1), unique(a+1, a+n+1)-a-1
// 离散化(首先排序,然后去重得到真实位次,最后进行对应)
sort(a, a+n); // 首先排序
int nn = unique(a, a+n)-a; // 然后得到真实的每个数的位次
for (int i = 0; i < n; ++i) b[i] = lower_bound(a, a+nn, b[i])-a;
for (int i = 0; i < n; ++i) printf("%d ", b[i]);
vector
#include <vector>
vector<int> b;
#include <algorithm>
int main(){
// 向量末尾插入元素
b.push_back(1);
// 向量开头插入元素
b.insert(b.begin(), 2); // 2 1
// 向量任意位置插入
int idx = 1;
b.insert(b.begin()+idx, 3); // 2 3 1 idx为1插入到索引为1的地方
// 移除
b.erase(b.begin()+idx); // 2 1 idx为1移除
// 带迭代器iteration的可以调整整个序列方向 => 注意是reverse,不是reserve;而且不是b.reverse,是外部的方法,包含在algorithm库中
reverse(b.begin(), b.end()); // 1 2
// 排序,sort外部的方法,包含在algorithm库中
sort(b.begin(), b.end());
// 查找
auto iter = find(b.begin(), b.end(), target_num);
if (iter != b.end()) printf("找到了");
else printf("没找到");
// 易错:vector移除队尾元素
b.erase(b.end()); // 会报错,因为b.end()实质上不是向量的最后一个,而是最后一个的下一个,就像find函数,看他是否有找到的实质就是看迭代器是否到了最后一个之后的end,而不是最后一个
b.pop_back(); // 正确写法
// 三种遍历方式
for (int i = 0; i < b.size(); i++) {b[i]}
for (int num: b) {num} / for (node nd: b) {nd.x, nd.y}
for (auto it = b.begin(); it != b.end();) {it->x, it->y}
// 边遍历,边移除=>在遍历的时候防止因为越界而报错(通过索引来进行访问,但是不方便移除操作;通过iterator进行访问,方便移除,并且方便将指针指向下一个元素)
for (auto it = b.begin(); it != b.end();) {
if (条件) it = b.erase(it); // 保证移除之后指针不会错误
else it++; // 不移除的话指针自动变化
}
}
queue
#include <queue>
queue<int> q;
int main(){
// 往优先队列中添加元素
q.push(2);
q.push(1);
// 获取队首 并 移除队首元素
int queue_front = q.front(); pq1.pop();
// 获取队尾
int queue_back = q.back();
}
priority_queue
#include <queue>
// 小顶堆 - 默认的int为容器中的元素
priority_queue<int, vector<int>, greater<int>> pq1;
// 大顶堆 - 默认的
priority_queue<int> pq2;
// 重载大于号的 - 容器元素为结构体node的
priority_queue<node, vector<node>, greater<node>> pq3;
// 重载小于号的 - 容器元素为结构体node的
priority_queue<node, vector<node>, less<node>> pq4;
int main(){
// 往优先队列中添加元素
pq1.push(2);
pq1.push(1);
// 获取队首 并 移除队首元素
int queue_top = pq1.top(); pq1.pop();
// 优先队列无法获取队尾,只能获取队首
}
优先队列结合重载运算符来使容器单元为结构体
// greater => 只能重载 > (大于号),重载成<会报错,因为greater是指利用>的比较方式
struct node{
int val;
bool operator > (const node n) const{return val>n.val;} // val的值由小到大
}
priority_queue<node, vector<node>, greater<node>> pq;
// less => 只能重载 < (小于号),重载成>会报错,因为less是指利用<进行比较的方式
struct node{
int val;
bool operator < (const node n) const{return val>n.val;} // val的值由小到大
}
priority_queue<node, vector<node>, less<node>> pq;
upperbound & lowerbound
#include <algorithm>
int main() {
int a = {1, 3, 6, 7, 14, 15, 18}, n=7; // 提前排好序的 或者 提前先排序的
int pos1 = lowerbound(a, a+n, 7); // 大于等于7的边界 => 3
int pos2 = upperbound(a, a+n, 7); // 大于7的边界 => 4
int b = {18, 15, 14, 7, 6, 3, 1}, n=7; //如果是反向的递减排序
int pos3 = lowerbound(b, b+n, 7); // 小于等于7的边界 => 3
int pos4 = lowerbound(b, b+n, 7); // 小于7的边界 => 4
}
auto
基于范围遍历 Range-Based-For (C++11之后支持)
std::vector<int> vec {1,2,3,4,5,6,7,8,9,10};
cout << "修改前" << endl;
for (auto& n :vec) // 将遍历的变量声明为引用类型,即可以修改内容
std::cout << n++;
cout << endl;
cout << "修改后" << endl;
for (auto j : vec)
std::cout << j;
std::vector<std::string> strs;
cout << "修改前" << endl;
for (auto && s :strs) { // 将遍历的变量声明为引用类型,即可以修改内容
std::cout << n+;
}
regex 模糊匹配
正则表达式 Regular Expression (C++11之后支持)
regex()
:解析正则项规则regex_match(被匹配字串, 采用regex封装的匹配**字串**)
:查看被匹配字串是否和被regex封装的拿去匹配的内容完全匹配,完全匹配返回true,不完全匹配返回false。- smatch=>得到regex的匹配结果
regex_search(被匹配字串, 采用regex封装的匹配**子串**)
:查看被匹配子串中有没有符合被regex封装的拿去匹配的部分,这样就有可能返回很多。- sregex_iterator=>得到search的匹配结果
regex_replace(被匹配字串,采用regex封装的匹配字串,被替换字串)
:查看被匹配字串中有没有符合被regex封装的拿去匹配的部分,并进行替换- 获取到多个模糊匹配单元=>整个算一个,下边部分匹配每个部分各自用括号括起来。(所以想获取到单独的值的话,从索引为1的地方开始遍历,因为第0的位置)
regex进行包装的部分,(以下全是regex引擎所识别的字符串,对于c代码的话,首先要进行转义)
- \d匹配数字大类:后面数字接长度
- \d{1}:一位的数字
- \d{4}:四位的数字
- \d+:不限制位数的数字
- .匹配所有:后面数字接长度
- .+:不限制位数的所有字符
#include <iostream>
using namespace std;
#include <regex>
int main() {
string str1 = "abc123def456xyz789t1";
string str2 = "123456789";
// 完全匹配-固定字串
cout<<regex_match(str1, regex("123"))<<"\n"; // 0 完全匹配不同
cout<<regex_match(str2, regex("123"))<<"\n"; // 0 完全匹配不同
cout<<regex_match(str1, regex("123456789"))<<"\n"; // 0
cout<<regex_match(str2, regex("123456789"))<<"\n"; // 1 完全匹配,字符串一模一样
// 完全匹配-仅通配符
cout<<regex_match(str1, regex("\\d+"))<<"\n"; // 0 完全匹配不同,因为要求的全是数字,而被匹配中有字符串
cout<<regex_match(str2, regex("\\d+"))<<"\n"; // 1 完全匹配,被匹配字符串中只有数字
// 完全匹配-存在外部字符+通配符
cout<<regex_match(str1, regex("abc123def456xyz(\\d+)"))<<"\n"; // 1 完全匹配,前面要相同部分,后面是通配部分
cout<<regex_match(str2, regex("abc123def456xyz(\\d+)"))<<"\n"; // 0 完全匹配不同,前面就不同。
printf("-------------\n");
// 搜索=>返回列表,用smatch
// 搜索-固定子串
smatch search_result;
// regex_search(str1, search_result, regex("123")); // 用承接的smatch穿进去来得到值
// cout<<search_result.size()<<"\n";
// for (int i = 0; i < search_result.size(); ++i) {
// cout<<search_result[i]<<"\n";;
// }
regex_search(str1, search_result, regex("abc(\\d+)def(\\d+)xyz(\\d+)t(\\d+)")); // 用承接的smatch穿进去来得到值
cout<<search_result.size()<<"\n";
for (int i = 0; i < search_result.size(); ++i) {
cout<<search_result[i]<<"\n";;
}
return 0;
}