CSP语法基础题(五)
CSP语法基础课(五)-容器STL
-
vector
vector是一个可以自动改变长度的数组
#include <iostream> #include <vector> using namespace std; int main(){ vector<int> a; //定义一个vector数组 vector<int> [100]; //定义100个vector,每一个都是长度动态变化的vector //所有的STL基本都有这俩函数 a.size(); a.empty(); //返回bool值 a.clear(); //迭代器定义iterator,就是C语言中的指针 vector<int> ::iterator it = a.begin(); // 类似指针it+2访问的就是a[2] cout << *it << " "<< *(it+2); *a.end(); //是最后一个元素的下一地址 效果等同于a[0] *a.begin(); //是第一个元素的地址 效果等同于a[a.size()-1] //初始化一个vector vector<int> z({1,2,3}); cout << *z.begin() << "==" << z[0] << endl; //所有容器都可以看做一个左闭右开的结构 //遍历方式一:数组一样 for(int i=0;i<z.size();i++) cout <<z[i]<<endl; //遍历方式二:迭代器 为了方便使用auto会非常方便 for(auto i=z.begin();i!=z.end();i++) cout << *i << endl; for(vector<int>::itrator i =z.begin();i!=z.end();i++) cout<<*i<<endl; //遍历方式三:范围遍历 for(int c:a) cout << c << endl; //front\back返回的是元素 back和迭代器end返回的略有不同,back返回的是最后一个元素 cout<< z.front() << " = " << *z.begin() << " = " << z[0] <<endl; cout<< z.back() << " = " << *(z.end()-1) << " = " << z[z.size()-1] <<endl; //push_back()数组的末尾添加元素 //pop_back()····而且这俩个函数对应的操作都是O(1)时间复杂度 z.push_back(4); z.pop_back(); //删除最后一个元素 // 也可以定义结构体vector struct Rec{ int x,y; } vector<Rec> c; return 0; }
vector实现原理:vector数组动态增长采用的是倍增技术。
-
queue
主要包括循环队列queue和优先队列priority_queue两个队列
#include<iostream>
#include<queue>
using namespace std;
int main(){
queue<int> q1;
queue<double> q2;
struct Rec{
int x,y;
double a,b;
}
queue<Rec> s[100] //和vector一样,这样定义其实也是一个二维空间,列表个数是100个,每个都是一个列表
//队列的性质 先进先出
return 0;
}
priority_queue 优先队列。一般默认的是每次弹出的是最大的元素
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
int main(){
queue<int> q;
q.push(1); //队尾插入
q.pop(); //队头弹出
q.front(); //返回队头元素
q.back(); //返回队尾元素
//大根堆
priority_queue<int> a; //定义一个大根堆
priority_queue<int,vector<int>,greater<int>> b; //定义小根堆,每次弹出最小值
a.push(1); //给队列插入元素
a.top(); //取出队列的最大值
a.pop(); //删除最大值
//自定义结构体放入优先队列的时候,要对小于号进行重载
struct Rec{
int x,y;
//这里要对小于号进行重载
};
priority_queue<Rec> a;
}
PS:队列、优先队列、栈没有clear()函数;
- stack
头文件include
和队列比较像,好多函数也是一样。先进后出罢了。
#include<stack>
using namespace std;
int main(){
stack<int> a;
a.push(1);
a.push(2);
a.pop();
a.pop();
return 0;
}
-
双端队列deque
两边都可以插入、删除的队列。优点像vector和queue的结合。与queue相比,deque支持随机访问;与vector相比,deque支持在头部增删元素O(1)
#include<deque>
deque<int> q; //定义
q.begin(),q.end(); //返回q的头尾迭代器
q.front(),q.back(); //直接返回头尾元素
q.push_back(1);//在deque最后插入一个元素
q.push_front(1); //在deque开头插入一个元素
q[i]; //支持随机访问
q.pop_back(); //删除最后一个元素
q.pop_front(); //删除第一个元素
q.clear(); //清空deque
-
set
#include<set> // 包含两种set和multiset set<int> a; //不能包含重复元素,如果插入重复元素,会忽略掉这个元素 multiset<int> b; //元素可以重复 //两种set实现基本相同,函数也是基本相同 // 也可以自己定义set元素类型 struct Rec{ int x,y; //这里还是需要重载小于号,因为set里的元素还是要做比较的 }; set<Rec> new_a; set<int> ::iterator it = a.begin(); it++; //迭代器加加表示有序序列的下一个元素 size/clear/empty也有 //插入一个元素 a.insert(x); //查找一个元素,会返回值等于x的一个迭代器;要是没有x,则会返回a.end()的迭代器 a.find(x); //查找一个大于等于元素x的最小元素的迭代器 a.lower_bound(); //查找一个大于元素x的最小元素的迭代器,这里之前理解错了,这里不是字面意思 a.upper_bound(); //查找元素x在a中出现的个数 ,set的话返回的是0或者1 a.count(x); //删除集合中值等于x的所有元素 a.erase(x);
-
map
#include<map>
using namespace std;
int main(){
map<int,int> a;
a[1] = 2; //存键值对1-2
a[10000] = 8; //存键值对10000-8
//当定义两个都是int型的时候,有点像是数组
map<string,int> b;
b["liufeng"] = 200;
b["wife"] = 2000;
cout << b["liufeng"] << endl; //输出的就是200
map<string,vector<int>> c;
c["liufeng"] = vector<int>({1,2,3});
cout << c["liufeng"][2] << endl; //输出的应该就是3
c.insert({"liufeng",{1,2,3}}); //除了上面赋值形式的插入,也可以使用insert函数
return 0;
}
-
unordered_set 无序set PS:只有在C++11里面才支持unordered_set和unordered_map
#include <unordered_set> int main(){ unorder_set <int> a; /*和set非常相像,但是没有lower_bound和upper_bound这两个函数(因为是无序的啊) 其余所有函数都是存在的,而且操作的效率是O(1),set数据操作的时间复杂度是 O(n) ,所以unorder_set的效率是比较高的。低层实现使用的哈希表。 */ unorder_multiset<int> b; //也是一个哈希表,顾名思义,集合的元素是可以重复的 }
-
unordered_map 时间效率也是比较高是,O(1)的,map的时间复杂度就比较低了是O(n),同样的也不支持二分
#include <unordered_map>
int main(){
unordered_map <int,int> b; //unordered_map也是操作效率比较高,各种查询操作的时间复杂度都是O(1)的,坏处是不支持二分
}
- bitset 这个是定义一个非常长的二进制串
#include <bitset>
using namespace std;
int main(){
bitset<1000> a; //括号里面写串的长度,定义了一个长度是1000位的01串
a[0] =1;
cout << a[0] << endl;
cout << a[1] << endl; //没有赋值的应该是0
a.count(); //返回里面1的个数
//也可以进行位运算& |
bitset<1000> b;
a &=b;
a |=b;
//set函数,可以把第几位设置成1
b.set(3);
b.set(4);
b.set(5);
cout << b[3] << b[4] << b[5] << endl;
b.reset(3);
b.reset(4); //把第4位设成0
b.reset(5); //把第5位设成0
return 0;
}
pair
pair<int,string> a; //pair和vector自带比较运算 支持 > 、<、==、!=、
a = {100,"liufeng"};
//c++99里面,pair只能使用make_pair来赋值
a = make_pair(4,"abc");
cout << a.first << " " << a.second << endl;