借鉴了https://www.cnblogs.com/happy-MEdge/p/11000156.html#7,https://blog.csdn.net/weixin_41162823/article/details/79759081两位大佬,感谢
Table of Contents
1.容器
2. String
int main(){
string s2;
s2 = s; //把s里面的内容复制到s2里面
string s3;
s3 = s + s2; //拼接s和s2然后复制到s3里面
s = s + s2; //把s2拼接到s末尾
int len = s.length(); //计算s的长度, 然后赋值到len,功能和strlen()一样,都不算'\0'
if(s[0] != 'a') s[0] = 'a'; //可以直接像char s[]一样访问和修改
int cnt = 0;
if(s == s2) cnt++; //可以直接比较s和s2是否相等
return 0;
}
3.vector
- vector是最简单也是最重要的一个容器。其头文件为<vector>.
- vector是数组的一种类表示,它有以下优点:自动管理内存、动态改变长度并随着元素的增减而增大或缩小。
- 在尾部添加元素是固定时间,在头部或中间添加或删除元素是线性时间。
- vector是可反转容器。下面以vector为例介绍可反转容器。
-
vector<int> a,b; //b为向量,将b的0-2个元素赋值给向量a a.assing(b.begin(),b.begin()+3); //a含有4个值为2的元素 a.assing(4,2); //返回a的最后一个元素 a.back(); //返回a的第一个元素 a.front(); //返回a的第i元素,当且仅当a存在 a[i]; //清空a中的元素 a.clear(); //判断a是否为空,空则返回true,非空则返回false a.empty(); //删除a向量的最后一个元素 a.pop_back(); //删除a中第一个(从第0个算起)到第二个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)结束 a.erase(a.begin()+1,a.begin()+3); //在a的最后一个向量后插入一个元素,其值为5 a.push_back(5); //在a的第一个元素(从第0个算起)位置插入数值5, a.insert(a.begin()+1,5); //在a的第一个元素(从第0个算起)位置插入3个数,其值都为5 a.insert(a.begin()+1,3,5); //b为数组,在a的第一个元素(从第0个元素算起)的位置插入b的第三个元素到第5个元素(不包括b+6) a.insert(a.begin()+1,b+3,b+6); //返回a中元素的个数 a.size(); //返回a在内存中总共可以容纳的元素个数 a.capacity(); //将a的现有元素个数调整至10个,多则删,少则补,其值随机 a.resize(10); //将a的现有元素个数调整至10个,多则删,少则补,其值为2 a.resize(10,2); //将a的容量扩充至100, a.reserve(100); //b为向量,将a中的元素和b中的元素整体交换 a.swap(b); //b为向量,向量的比较操作还有 != >= > <= < a==b;
4.map
#include <cstdio>
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main(){
//map用法介绍
map<string, int> mp; //创建一个map: 从string到1的映射
mp["abc"] = 1; //建立从字符串"abc"到整数1的映射
string s = "efg"; //创建一个string
mp[s] = 5; //建立从字符串"efg"到整数5的映射
//访问
int a;
a = mp["abc"]; //这时mp["abc"]的值为1, 也就是a = 1
cout << a << endl;
a = mp[s]; //这时mp[s]的值为5, 也就是a = 5
cout << a << endl;
//使用char数组
char s2[5] = "gsd";
mp[s2] = 9; //建立从字符串"gsd"到整数9的映射
cout << mp[s2] << endl;
mp.clear(); //清空mp里面的元素, 相当于把所有映射都抹去
//最后注意的是, 虽然map看起来很像hash, 但其内部实现不是hash, 而是一颗树(红黑树)
//也就是说, 当进行访问map的操作时, 时间复杂度为O(log m)(m为映射数量), 并不是O(1)
return 0;
}
5.queue
- 头文件<queue>
- queue不允许随机访问队列元素,不允许遍历队列,可以进行队列基本操作
- 可以将元素添加到队尾,从队首删除元素,查看队尾和队首的值,检查元素数目和测试队列是否为空
-
queue的操作:
int main(){
//queue基本用法
queue<int> q; //创建一个先进先出的队列(也就是这个队列只能在尾部加入元素, 头部取出元素, 这个是关键)
q.push(1); //加入元素1
q.push(2); //加入元素2
q.push(3); //加入元素3
//这时队列是: 1, 2, 3
//访问
int a;
a = q.front(); //这时q.front()的值为1, 所以a = 1, 注意这里只是读取队列首元素, 并没有弹出元素
//弹出
q.pop(); //弹出队列的首元素, 也就是变成2, 3
//判断队列是否为空
q.pop(); //弹出队列的首元素, 也就是变成3
q.pop(); //弹出队列的首元素, 此时队列为空
if(q.empty()) cout << "Yes\n"; //如果队列为空, 则q.empty()为真, 则输出"Yes"
if(q.size() == 0) cout << "Yes\n"; //如果队列大小为0, 则输出"Yes"
return 0;
}
6.sort
bool cmp1(int x, int y){
return x > y; //从大到小排
}
bool cmp2(int x, int y){
return x < y; //从小到大排
}
bool cmp_node(node x, node y){
if(x.first == y.first) return x.second < y.second;
else return x.first < y.first;
//这里的意思: 优先对结构体的第一个值进行排序, 如果第一个值相等, 就按照第二个值进行排序
}
int main(){
//sort的用法
int a[5] = {5,4,3,2,1};
sort(a, a+5); //默认对数组a进行从小到大排序
string s[3] = {"bcd", "abc", "a"};
sort(s, s+3); //默认对字符串进行字典序排序
//自定义比较级(比较函数):
sort(a, a+5, cmp1); //按cmp1的比较级排序, 注意这里cmp1后面不能加()
sort(a, a+5, cmp2); //按cmp2的比较级排序
//对结构体进行排序
node G[3] = {{5,3}, {5, 2}, {1, 9}};
sort(G, G+3, cmp_node); //按照cmp_node进行排序
return 0;
}
7.priority_queue:优先队列
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
//从主函数看起
struct node{
int first, second;
};
struct cmp1{ //这里比较级是用结构体, 而不是函数
bool operator () (int a, int b){ //重载操作, 记住就行
return a > b;
//小的优先在前面, 因为是用"堆"去实现的, 不清楚堆就直接记住和sort的cmp刚好相反
}
};
struct cmp2{
bool operator () (node a, node b){
if(a.first == b.first) return b.second > b.second;
return a.first > b.first;
}
};
int main(){
//priority_queue基本用法
priority_queue<int> q; //创建一个优先队列
q.push(1); //加入元素1
q.push(3); //加入元素3
q.push(2); //加入元素2
if(!q.empty()) printf("YES\n"); //q.empty():判断优先队列是否为空
int a;
while(!q.empty()){
a = q.top(); //这里只是读取队列首元素, 并没有弹出元素
printf("%d ", a);
q.pop(); //弹出首元素
}
printf("\n");
//运行上面程序,发现输出为:3, 2, 1, 也就是说, 默认优先队列默认从大到小排列
priority_queue<int, vector<int>, less<int> > q_less;
//创建一个优先级为:从大到小, 排的优先队列
priority_queue<int, vector<int>, greater<int> > q_great;
//创建一个优先级为:从小到大, 排的优先队列
priority_queue<int, vector<int>, cmp1> q_cmp1;
//自定义比较级:cmp1
priority_queue<node, vector<node>, cmp1> q_cmp1;
//自定义比较级:cmp2
return 0;
}
8.list
- list表示双向链表。头文件<list>
- list为可反转容器。
- list不支持数组表示法和随机访问。
- 与矢量迭代器不同,从容器中插入或删除元素之后,链表迭代器指向的元素不变。这与链表的特性有关,删除链表中的元素并不改变其它元素位置,只是修改链接信息。(代码证明)
- 不同于vector,list不强调随机访问与快速访问,list强调的是元素的快速插入与删除
- 再次提醒:序列容器都是线性排序,因此list首尾不会相连。
- list成员函数:
int main()
{
list<int> dice(5,2);//一种赋初值方法。5个2
int a[] = {1,5,4,3};
dice.insert(dice.begin(),a,a+4);//insert函数用法
list<int> two(dice);//另一种赋初值方法,其值与dice相等
dice.splice(dice.begin(),two);//splice函数用法
two = dice;
dice.unique();//unique压缩连续相同的元素
dice.sort();//sort函数用法
two.sort();
dice.merge(two);//merge函数用法,将two合并到dice中,two将为空。
dice.remove(2);//移除所有2
return 0;
}
9.stack
- 头文件<stack>
- stack是一个适配器,它给底层类(默认vector)提供典型栈接口。
- stack不允许随机访问栈元素,不允许遍历栈,把使用限制在定义栈的基本操作上
- 可以将值压入栈顶,从栈顶弹出元素,查看栈顶的值,检查元素数目,测试栈是否为空
- stack的操作:
-
#include <iostream> #include<stack> using namespace std; int main() { stack<int> s; s.push(1); //入栈 s.push(2); s.push(3); s.push(34); cout << s.top() << endl; //栈顶元素 s.pop(); //出栈 cout << s.top() << endl; s.push(23); cout << s.top() << endl; while (!s.empty()) { //栈是否为空,栈为空则真 cout << s.size() << endl; //栈的大小 cout <<s.top()<< endl; s.pop(); } }