冲刺蓝桥杯第四章标准模版库STL(上)

2024-08-30 05:52

本文主要是介绍冲刺蓝桥杯第四章标准模版库STL(上),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

vector:

介绍:

vector 是 C++ 标准模板库(STL)中的一个非常重要的序列容器,它封装了动态数组的实现。vector 能够存储具有相同类型的元素序列,并且能够根据需要自动调整其大小。注意:在局部区域中(比如局部函数里面)开vector数组,是在堆空间里面开的。在局部区域开数组是在栈空间开的,而栈空间比较小,如果开了非常长的数组就会发生爆栈。故局部区域不可以开大长度数组,但是可以开大长度 vector 。
1、头文件:

#include <vector>

2、一维初始化:

vector<int> v; // 定义了一个名为v的一维数组,数组存储int类型数据
vector<double> v; // 定义了一个名为v的一维数组,数组存储double类型数据
vector<node> v; // 定义了一个名为v的一维数组,数组存储结构体类型数据,node是结构体类型

指定长度和初始值的初始化:

vector<int> v(n); // 定义一个长度为n的数组,初始值默认为0,下标范围[0, n - 1]
vector<int> v(n, 1); // v[0] 到 v[n - 1]所有的元素初始值均为1
//注意:指定数组长度之后(指定长度后的数组就相当于正常的数组了)

初始化中有多个元素:

vector<int> a{1, 2, 3, 4, 5}; // 数组a中有五个元素,数组长度就为5

拷贝初始化:

vector<int> a(n + 1, 0);
vector<int> b(a); // 两个数组中的类型必须相同,a和b都是长度为n+1,初始值都为0的数组
vector<int> c = a; // 也是拷贝初始化,c和a是完全一样的数组

3、二维初始化:
定义第一维固定长度为 5 ,第二维可变化的二维数组:

vector<int> v[5]; // 定义可变长二维数组
//注意:行不可变(只有5行), 而列可变,可以在指定行添加元素
//第一维固定长度为5,第二维长度可以改变

vector v[5] 可以这样理解:长度为5的v数组,数组中存储的是 vector 数据类型,而该类型就是数组形式,故 v 为二维数组。其中每个数组元素均为空,因为没有指定长度,所以第二维可变长。可以进行下述操作:

v[1].push_back(2);
v[2].push_back(3);

定义行列均可变的二维数组:

//初始化二维均可变长数组
vector<vector<int> > v; // 定义一个行和列均可变的二维数组,注意哦,>>之间要加上空

可以在 v 数组里面装多个数组:

vector<int> t1{1, 2, 3, 4};
vector<int> t2{2, 3, 4, 5};
v.push_back(t1);
v.push_back(t2);
v.push_back({3, 4, 5, 6}) // {3, 4, 5, 6}可以作为vector的初始化,相当于一个无名vector

行列长度均固定 n + 1 行 m + 1 列初始值为0:

vector<vector<int > a(n + 1, vector<int>(m + 1, 0));

常用函数:

#include<iostream>
#include<vector>
using namespace std;
vector<int>v;
int main(){v.push_back(1);//在尾部加一个元素  O(1)v.front();//返回第一个元素  O(1)v.back();//返回数组中的最后一个元素  O(1)v.pop_back();//删除最后一个元素  O(1)v.size();//返回元素的个数(unsigned类型)  O(1)v.clear();//清除元素个数  O(n) n为元素个数v.resize(n,v);//改变数组大小为n,n个空间数值赋为v,没有v时默认为零v.insert(it,x);//向任一迭代器it插入一个元素x  O(n)//例子:v.insert(v.begin(),1)将1插入到v[0]的位置v.erase(first,last);//删除[first,last)的所有元素  O(n)v.begin();//返回首元素的迭代器(类似于地址) O(1)v.end();//返回尾元素的下一个位置的迭代器  O(1)v.empty();//判断是否为空,为空返回真,反之返回假  O(1)
}

访问:

共三种方法:
1、下标法:直接和普通数组一样进行访问即可。
注意:一维数组的下标是从 0 到 v.size()-1 ,访问之外的数会出现越界错误

#include<iostream>
#include<vector>
using namespace std;
vector<int>v;
int main(){int n,t;cin>>n;for(int i=0;i<n;i++){cin>>t;v.push_back(t);}for(int i=0;i<n;i++){cout<<v[i];}return 0;
}

2、迭代器法 :类似指针,迭代器就是充当指针的作用。

vector<int> vi{1, 2, 3, 4, 5};
//迭代器访问
vector<int>::iterator it;
//相当于声明了一个迭代器类型的变量it,通俗来说就是声明了一个指针变量

方法一:

#include<iostream>
#include<vector>
using namespace std;
vector<int>v;
int main(){int n,t;cin>>n;for(int i=0;i<n;i++){cin>>t;v.push_back(t);}vector<int>::iterator it=v.begin();for(int i=0;i<n;i++){cout<<*(it+i);}return 0;
}

方法二:

#include<iostream>
#include<vector>
using namespace std;
vector<int>v;
int main(){int n,t;cin>>n;for(int i=0;i<n;i++){cin>>t;v.push_back(t);}vector<int>::iterator it;for(it=v.begin();it!=v.end();it++){//注意不能用小于只能使用不等于cout<<*it;}return 0;
}

方法三:

#include<iostream>
#include<vector>
using namespace std;
vector<int>v;
int main(){int n,t;cin>>n;for(int i=0;i<n;i++){cin>>t;v.push_back(t);}auto it=v.begin();while(it!=v.end()){cout<<*it;it++;}return 0;
}

3、智能指针:使用auto :比较简便,但是只能访问数组的所有元素(特别注意0位置元素也会访问到)如果要对部分内容进行遍历,需要另选方法。
auto 能够自动识别并获取类型。

#include<iostream>
#include<vector>
using namespace std;
int main(){int n;cin>>n;vector<int>v(n);//使用auto必须要有输入数量//输入for(auto &x:v){cin>>x;}//输出for(auto val:v){cout<<val;}return 0;
}

vector 注意:
vi[i] 和 *(vi.begin() + i) 等价,与指针类似。
vector 和 string 的 STL 容器支持 *(it + i) 的元素访问。

stack

介绍

栈是STL中实现的一个先进后出,后进先出的容器。
1、头文件

#include<stack>

2、初始化

stack<int> s;
stack<string> s;
stack<node> s; // node是结构体类型

常用函数

#include<iostream>
#include<stack>
using namespace std;
stack<int>s;
int main(){s.push(n);//将元素n入栈  O(1)s.pop();//移除栈顶元素  O(1)s.top();//取出栈顶元素  O(1)s.empty();//检测栈内是否为空,空为真,非空为假  O(1)s.size();//返回栈内的元素个数  O(1)
}

遍历

1、栈只能对栈顶元素进行操作,如果想要进行遍历,只能将栈中元素一个个取出来存在数组中

#include<iostream>
#include<stack>
using namespace std;
stack<int>s;
int main(){int n;cin>>n;for(int i=0;i<n;i++){int x;cin>>x;s.push(x);}while(!s.empty()){int tp=s.top();s.pop();cout<<tp;}
}

2、数组模拟栈进行遍历:通过一个数组对栈进行模拟,一个存放下标的变量 top 模拟指向栈顶的指针。
一般来说单调栈和单调队列写法均可使用额外变量 tt 或 hh 来进行模拟。
特点: 比 STL 的 stack 速度更快,遍历元素方便

int s[100]; // 栈 从左至右为栈底到栈顶
int tt = -1; // tt 代表栈顶指针,初始栈内无元素,tt为-1
for(int i = 0; i = 5; i++) {//入栈s[++tt] = i;
}
//出栈
int top_element = s[tt--];
//入栈操作示意
//0 1 2 3 4 5
//          tt
//出栈后示意
//0 1 2 3 4
//        tt 

queue

介绍:

队列是一种先进先出的数据结构。
1、头文件:

#include<queue>

2、初始化:

queue<int> q;

常用函数:

#include<iostream>
#include<queue>
using namespace std;
queue<int>q;
int main(){q.push(n);//将n元素入队  O(1)q.front();//返回队首元素  O(1)q.back();//返回队尾元素  O(1)q.pop();//删除第一个元素(出队)  O(1)q.size();//返回队列中元素的个数,返回值类型unsigned int  O(1)q.empty();//判断队列是否为空,队列为空返回true,为非空返回false  O(1)
}

对列模拟

使用 q[] 数组模拟队列
hh 表示队首元素的下标,初始值为 0
tt 表示队尾元素的下标,初始值为 -1 ,表示刚开始队列为空

#include<iostream>
using namespace std;
const int N = 1e5 + 5;
int q[N];
int main(){int hh = 0,tt = -1;//入队q[++tt] = 1;q[++tt] = 2;//将所有元素出队while(hh = tt) {int t = q[hh++];printf("%d ",t);}return 0;
}

deque

介绍

首尾都可插入和删除的队列为双端队列,在两端都可以进行操作。
1、头文件

#include<deque>

2、初始化

deque<int> dq;

常用函数

#include<iostream>
#include<deque>
using namespace std;
deque<int>dq;
int main(){dp.push_back(n);//把元素n插入到队尾  O(1)dp.push_front(n);//把元素n插入到队首  O(1)dp.back();//返回队尾元素  O(1)dp.front();//返回队首元素  O(1)dp.pop_back();//删除队尾元素  O(1)dp.pop_front();//删除队首元素  O(1)dp.erase(iterator it);//删除双端队列中的某一个元素dp.erase(iterator first,iterator last);//删除双端队列中[first,last)中的元素dp.empty();//判断双端队列是否为空  O(1)dp.size();//返回双端队列的元素数量  O(1)dp.clear();//清空双端队列
}

注意点

deque可以进行排序(双端队列排序一般不用,使用其他STL依然可实现相同功能)

//从小到大
sort(dq.begin(), dq.end())
//从大到小排序
sort(dq.begin(), dq.end(), greater<int>()); // deque里面的类型需要是int型
sort(dq.begin(), dq.end(), greater());//c++高版本才可以用

priority_queue

介绍:

优先队列是一种特殊的队列,其中每个元素都被赋予一个优先级。在优先队列中,元素的出队顺序不是基于它们的入队顺序,而是基于它们的优先级。优先级最高的元素会最先被移除。优先队列分为最大优先队列和最小优先队列,前者总是移除当前优先级最高的元素(即最大的元素),后者总是移除当前优先级最低的元素(即最小的元素)。
优先队列的实现通常基于堆数据结构,特别是二叉堆。堆是一个近似完全二叉树的结构,并同时满足堆属性:即子节点的键值或索引总是小于(或大于)它的父节点。通过堆的性质,优先队列可以在对数时间复杂度内完成插入和删除最大(或最小)元素的操作。
1、头文件

#include<queue>

2、初始化

priority_queue<int> q;

常用函数:

#include<iostream>
#include<queue>
using namespace std;
priority_queue<int>q;
int main(){q.top();//访问队首元素  O(1)q.push(n);//将n入队  O(logn)q.pop();//堆顶(队首)元素出队  O(logn)q.size();//队列元素个数  O(1)q.empty();//判断是否为空,空为真,非空为假  O(1)//注意:优先队列没有clear()//优先队列只能通过 top() 访问队首元素(优先级最高的元素)
}

设置优先级

1、基本数据类型的优先级

priority_queue<int> q; // 默认大根堆, 即每次取出的元素是队列中的最大值
priority_queue<int, vector<int>, greater<int> > q; // 小根堆, 每次取出的元素是队列中的最小值

参数解释:
第一个参数:
就是优先队列中存储的数据类型
第二个参数:
vector 是用来承载底层数据结构堆的容器,若优先队列中存放的是 double 型数据,就要填 vector< double >总之存的是什么类型的数据,就相应的填写对应类型。同时也要改动第三个参数里面的对应类型。
第三个参数:
less 表示数字大的优先级大,堆顶为最大的数字
greater 表示数字小的优先级大,堆顶为最小的数字
int代表的是数据类型,也要填优先队列中存储的数据类型
基础数据类型优先级设置的写法:
<1>、基础写法:

priority_queue<int> q1; // 默认大根堆, 即每次取出的元素是队列中的最大值
priority_queue<int, vector<int>, less<int> > q2; // 大根堆, 每次取出的元素是队列中的最大值,同第一行
priority_queue<int, vector<int>, greater<int> > q3; // 小根堆, 每次取出的元素是队列中的最小值

<2>、自定义排序:

struct cmp1 {bool operator()(int x, int y) {return x > y;}
};
struct cmp2 {bool operator()(const int x, const int y) {return x < y;}
};
priority_queue<int, vector<int>, cmp1> q1; // 小根堆
priority_queue<int, vector<int>, cmp2> q2; // 大根堆

2、高级数据类型(结构体)优先级:即优先队列中存储结构体类型,必须要设置优先级,即结构体的比较运算(因为优先队列的堆中要比较大小,才能将对应最大或者
最小元素移到堆顶)。
优先级设置可以定义在结构体内进行小于号重载,也可以定义在结构体外。

//要排序的结构体(存储在优先队列里面的)
struct Point {int x, y;
};

<1>、自定义全局比较规则

//定义的比较结构体
//注意:cmp是个结构体
struct cmp { // 自定义堆的排序规则bool operator()(const Point& a,const Point& b) {return a.x < b.x;}
};
//初始化定义
priority_queue<Point, vector<Point>, cmp> q; // x大的在堆顶

<2>、直接在结构体里面写:因为是在结构体内部自定义的规则,一旦需要比较结构体,自动调用结构体内部重载运算符规则。
结构体内部有两种方式:
方式一 :

struct node {int x, y;friend bool operator < (Point a, Point b) { // 为两个结构体参数,结构体调用一定要写上friendreturn a.x < b.x; // 按x从小到大排,x大的在堆顶}
};

方式二 :(推荐)

struct node {int x, y;bool operator < (const Point &a) const { // 直接传入一个参数,不必要写friendreturn x < a.x; // 按x升序排列,x大的在堆顶}
};

优先队列的定义:

priority_queue<Point> q;

注意: 优先队列自定义排序规则和 sort() 函数定义 cmp 函数很相似,但是最后返回的情况是相反的。即相同的符号,最后定义的排列顺序是完全相反的。
所以只需要记住 sort 的排序规则和优先队列的排序规则是相反的就可以了。
3、存储特殊类型的优先级
存储pair类型:
排序规则:
默认先对 pair 的 first 进行降序排序,然后再对 second 降序排序
对 first 先排序,大的排在前面,如果 first 元素相同,再对 second 元素排序,保持大的在前面。

#include<iostream>
#include<queue>
using namespace std;
int main() {priority_queue<pair<int, int> >q;q.push({7, 8});q.push({7, 9});q.push(make_pair(8, 7));while(!q.empty()) {cout << q.top().first << " " << q.top().second;q.pop();}return 0;
}
//结果:
//8 7
//7 9
//7 8

map

介绍

映射类似于函数的对应关系,每个 key 对应一个 value ,而 map 是每个键对应一个值。
1、头文件

#include<map>

2、初始化

map<string, string> mp;
map<string, int> mp;
map<int, node> mp; // node是结构体类型

map特性:map会按照键的顺序从小到大自动排序,键的类型必须可以比较大小

常用函数

#include<iostream>
#include<map>
using namespace std;
map<int ,int>mp;
int main() {mp.find(key);//返回健为key的映射的迭代器  O(logN)//注意:用find函数来定位数据出现的位置,它返回一个迭代器。当数据存在时,返回数据所在位置的迭代器,当数据不存在时,返回mp.end()mp.erase(it);//删除迭代器对应的键和值  O(1)mp.erase(key);//根据映射的键删除键和值  O(logN)mp.erase(first,last);//删除[first,last)区间的迭代器对应的键和值  O(last-first)mp.size();//返回映射的对数  O(1)mp.clear();//清空map中的所有元素  O(n)mp.insert();//插入元素,插入时要构造键值对mp.empty();//判断map是否为空,为空返回true,为假返回falsemp.begin();//返回指向map第一个元素的迭代器(地址)mp.end();//返回指向map最后一个元素的下一个地址mp.rbegin();//返回指向map最后一个元素的迭代器(地址)mp.rend();//返回指向元素map第一个元素的前一个地址(逆向迭代器)mp.count(key);//查看元素是否存在,因为map中的键值是唯一的,存在返回true,不存在返回falsemp.lower_bound();//返回一个迭代器,指向键值>=key的第一个元素mp.upper_bound();//返回一个迭代器,指向键值>key的第一个元素
}

注意点:
查找元素是否存在时,可以使用① mp.find() ② mp.count() ③ mp[key]但是第三种情况,如果不存在对应的 key 时,会自动创建一个键值对(产生一个额外的键值对空间)所以为了不增加额外的空间负担,最好使用前两种方法。

迭代器进行正反向遍历:

1、mp.begin() 和 mp.end() 用于正向遍历map

#include<iostream>
#include<map>
using namespace std;
map<int ,int>mp;
int main() {int n;cin>>n;for(int i=1;i<=n;i++){int x,y;cin>>x>>y;mp[x]=y;}auto it=mp.begin();while(it!=mp.end()){cout<<it->first<<" "<<it->second<<endl;it++;}
}

2、mp.rbegin() 和 mp.rend()用于逆向遍历map

#include<iostream>
#include<map>
using namespace std;
map<int ,int>mp;
int main() {int n;cin>>n;for(int i=1;i<=n;i++){int x,y;cin>>x>>y;mp[x]=y;}auto it=mp.rbegin();while(it!=mp.rend()){cout<<it->first<<" "<<it->second<<endl;it++;}
}

二分查找:

map的二分查找以第一个元素(即键为准),对键进行二分查找返回值为map迭代器类型

#include<iostream>
#include<map>
using namespace std;
map<int ,int>mp{{1,2},{2,2},{3,2},{6,2},{8,2}};//有序
int main() {//判断的是key返回的也是key的值map<int ,int>::iterator it1=mp.lower_bound(2);//左边界cout<<it1->first;//2map<int ,int>::iterator it2=mp.upper_bound(6);//右边界cout<<it2->first;//8return 0;
}

添加元素:

先声明:

map<string ,string>mp;

方法一:

mp["abcd"]="abcd";

方法二:

mp.insert(make_pair("abcd","abcd"));

方法三:

mp.insert(pair<string ,string>("abcd","abcd"));

方法四:

mp.insert({"abcd","abcd"});

访问元素

1、下标访问:

#include<iostream>
#include<map>
using namespace std;
map<string ,string>mp;
int main() {mp["abcd"]="efg";cout<<mp["abcd"];
}

2、遍历访问:
方法一:迭代器访问

#include<iostream>
#include<map>
using namespace std;
map<string ,string>mp;
int main() {mp["abcd"]="efg";map<string ,string>::iterator it;for(it=mp.begin();it!=mp.end();it++){cout<<it->first<<" "<<it->second;//it是结构体指针访问要用  ->  访问cout<<(*it).first<<" "<<(*it).second;//*it是结构体变量访问要用  .  访问}
}

方法二:智能指针

#include<iostream>
#include<map>
using namespace std;
map<string ,string>mp;
int main() {mp["abcd"]="efg";map<string ,string>::iterator it;for(auto i:mp){cout<<i.first<<" "<<i.second;}
}

方法三:对指定单个元素访问

#include<iostream>
#include<map>
using namespace std;
map<string ,string>mp;
int main() {mp["abcd"]="efg";map<string ,string>::iterator it=mp.find("abcd");//key的值cout<<it->first<<" "<<it->second;
}

方法四:c++17特性

#include<iostream>
#include<map>
using namespace std;
map<string ,string>mp;
int main() {mp["abcd"]="efg";for(auto [x,y]:mp){cout<<x<<" "<<y;}
}

map与unordered_map的比较

头文件:

#include <unordered_map>

1、内部实现原理
map:内部用红黑树实现,具有自动排序(按键从小到大)功能。
unordered_map:内部用哈希表实现,内部元素无序杂乱。
2、效率比较
map:
优点:内部用红黑树实现,内部元素具有有序性,查询删除等操作复杂度为O(logN)
缺点:占用空间,红黑树里每个节点需要保存父子节点和红黑性质等信息,空间占用较大。
unordered_map:
优点:内部用哈希表实现,查找速度非常快(适用于大量的查询操作)。
缺点:建立哈希表比较耗时。
两者方法函数基本一样,差别不大。
注意:
随着内部元素越来越多,两种容器的插入删除查询操作的时间都会逐渐变大,效率逐渐变低。
使用 [] 查找元素时,如果元素不存在,两种容器都是创建一个空的元素;如果存在,会正常索引对应的值。所以如果查询过多的不存在的元素值,容器内部会创建大量的空的键值对,后续查询创建删除效率会大大降低。
查询容器内部元素的最优方法是:先判断存在与否,再索引对应值(适用于这两种容器)

#include<iostream>
#include<map>
using namespace std;
map<string ,string>mp;
int main() {mp["abcd"]="efg";string s="abcd";//key的值if(mp.count(s)){cout<<mp[s];}
}

multimap

键可以重复,即一个键对应多个值。
1、头文件:

#include<map>

2、初始化:
方法一:

multimap<string, int> mymultimap{{"penny",1},{"leonard",2},{"sheldon",3}};

方法二:

//借助pair类模板的构造函数生成各个pair类型的键值对
multimap<string,int> mymultimap{pair<string,int>{"penny",1},pair<string,int>{"leonard",2},pair<string,int>{"sheldon",3}
};
//调用make_pair()函数,生成键值对元素;然后创建并初始化multimap容器
multimap<string,int> mymultimap{make_pair("penny", 1),make_pair("leonard",2),make_pair("sheldon",3)
};

方法三:
拷贝(复制)构造函数,也可以初始化新的multimap容器。

//创建一个会返回临时multimap对象的函数
multimap<string,int> tmpmultimap(){multimap<string,int> tempmultimap{{"penny",1},{"leonard",2}};return tempmultimap;
}
//在main函数中调用multimap类模板的移动构造函数创建newmultimap容器
multimap<string,int> newmultimap(tmpmultimap());

方法四:
multimap类模板还支持从已有的multimap容器中,选取某块区域内的所有键值对,用作初始化新multimap容器时使用。

#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(){//创建并初始化multimap容器multimap<string,int> mymultimap{{"penny",1},{"leonard",2},{"sheldon",3},{"howard",4}};multimap<string,int> newmultimap(++mymultimap.begin(),mymultimap.end());      for(auto iter = newmultimap.begin(); iter != newmultimap.end(); iter++){cout<<iter->first<<" "<<iter->second<<endl;}return 0;
}

和map容器相比,multimap未提供at()成员方法,也没有重载[ ] 运算符。map容器中通过指定键获取指定键值对的方式,将不再适用于multimap容器。multimap容器提供的成员方法,map容器都有提供,并且它们的用法是相同的。

这篇关于冲刺蓝桥杯第四章标准模版库STL(上)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1119966

相关文章

数据治理框架-ISO数据治理标准

引言 "数据治理"并不是一个新的概念,国内外有很多组织专注于数据治理理论和实践的研究。目前国际上,主要的数据治理框架有ISO数据治理标准、GDI数据治理框架、DAMA数据治理管理框架等。 ISO数据治理标准 改标准阐述了数据治理的标准、基本原则和数据治理模型,是一套完整的数据治理方法论。 ISO/IEC 38505标准的数据治理方法论的核心内容如下: 数据治理的目标:促进组织高效、合理地

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚:

C 标准库 - `<float.h>`

C 标准库 - <float.h> 概述 <float.h> 是 C 标准库中的一个头文件,它定义了与浮点数类型相关的宏。这些宏提供了关于浮点数的属性信息,如精度、最小和最大值、以及舍入误差等。这个头文件对于需要精确控制浮点数行为的程序非常有用,尤其是在数值计算和科学计算领域。 主要宏 <float.h> 中定义了许多宏,下面列举了一些主要的宏: FLT_RADIX:定义了浮点数的基数。

模版方法模式template method

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法

STL经典案例(四)——实验室预约综合管理系统(项目涉及知识点很全面,内容有点多,耐心看完会有收获的!)

项目干货满满,内容有点过多,看起来可能会有点卡。系统提示读完超过俩小时,建议分多篇发布,我觉得分篇就不完整了,失去了这个项目的灵魂 一、需求分析 高校实验室预约管理系统包括三种不同身份:管理员、实验室教师、学生 管理员:给学生和实验室教师创建账号并分发 实验室教师:审核学生的预约申请 学生:申请使用实验室 高校实验室包括:超景深实验室(可容纳10人)、大数据实验室(可容纳20人)、物联网实验

C++ STL 适配器

系列文章目录 模板特例化,偏特化,左右值引用 https://blog.csdn.net/surfaceyan/article/details/126794013 C++ STL 关联容器 https://blog.csdn.net/surfaceyan/article/details/127414434 C++ STL 序列式容器(二) https://blog.csdn.net/surfac

C语言蓝桥杯

一、语言基础 竞赛常用库函数 最值查询 min_element和max_element在vector(迭代器的使用) nth_element函数的使用 例题lanqiao OJ 497成绩分析 第一种用min_element和max_element函数的写法 第二种用min和max的写法 二分查找 二分查找只能对数组操作 binary_s

【CSS in Depth 2 精译_023】第四章概述 + 4.1 Flexbox 布局的基本原理

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一章 层叠、优先级与继承(已完结) 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位(已完结) 2.1 相对单位的威力2.2 em 与 rem2.3 告别像素思维2.4 视口的相对单位2.5 无单位的数值与行高2.6 自定义属性2.7 本章小结 第三章 文档流与盒模型(已

《C++标准库》读书笔记/第一天(C++新特性(1))

C++11新特性(1) 以auto完成类型自动推导 auto i=42; //以auto声明的变量,其类型会根据其初值被自动推倒出来,因此一定需要一个初始化操作; static auto a=0.19;//可以用额外限定符修饰 vector<string> v;  auto pos=v.begin();//如果类型很长或类型表达式复杂 auto很有用; auto l=[] (int

C++ STL关联容器Set与集合论入门

1. 简介 Set(集合)属于关联式容器,也是STL中最实用的容器,关联式容器依据特定的排序准则,自动为其元素排序。Set集合的底层使用一颗红黑树,其属于一种非线性的数据结构,每一次插入数据都会自动进行排序,注意,不是需要排序时再排序,而是每一次插入数据的时候其都会自动进行排序。因此,Set中的元素总是顺序的。 Set的性质有:数据自动进行排序且数据唯一,是一种集合元素,允许进行数学上的集合相