v e c t o r vector vector直译为“向量”,一般说成“变长数组”,也就是长度根据需要而自动改变的数组,有些题目需要开很多数组,往往造成内存超限,使用 v e c t o r vector vector简单方便,还可节省空间,使用 v e c t o r vector vector,必须加#include
及using namespace std;
。
vector<typename> name;
其中typename
为数据类型,name
为定义的不定长数组的数组名
eg.vector
表示定义了一个数据类型为int,名为v的不定长数组
其中typename
也可以是一个STL容器
vector<vector<int> > a; //定义了一个两个维度都可变的二维整型数组a
注意vector
访问vector中的元素一般有两种方式:下标访问 和 迭代器(iterator)访问
对于容器vector
可以将迭代器理解为一种类似指针的变量,使用前需要提前定义,其定义为:vector
vector<int>::iterator it = v.begin(); //定义一个迭代器it,初始化为容器v的首元素地址
*it//相当于v[0];
*(it + i)//相当于v[i]。
迭代器还可以进行自加自减操作,如it++,++it,it–,--it
,注意:迭代器不支持“it
it != v.end()
”, v.end()并不是取v容器尾元素地址,而是尾元素下一个地址。
for(vector<int>::iterator it=v.begin();it!=v.end();it++){
printf("%d",*it);
}
push_back(x)将x添加到容器最后,并相应让长度+1,时间复杂度为 O ( 1 ) O(1) O(1)。
size()用来获得vector中元素个数,时间复杂度为O(1),同时,还可以使用resize(n)重设数组大小。例如以下代码输出12300:
vector<int> v;
for(int i=1;i<=3;i++){
v.push_back(i);
}
v.resize(5);
for(int i=0;i<v.size();i ++){
printf("%d",v[i]);
}
用来删除vector中的尾元素,并相应让长度-1。时间复杂度为O(1),例如以下代码输出12:
vector<int> v;
for(int i=1;i<=3;i ++){
v.push_back(i);
}
v.pop_back();
for(int i=0;i<v.size();i++){
printf("%d",v[i]);
}
用来清空vector中的所有元素。时间复杂度为O(n),例如以下代码输出0:
vector<int> v;
for(int i=1;i<=3;i ++){
v.push_back(i);
}
v.clear();
printf("%d",v.size());
insert(it, x)用来向vector任意迭代器it处插入元素x。时间复杂度为O(n),例如以下代码输出1 2 -1 3 4 5:
vector<int> v;
for(int i=1;i<=5;i++){
v.push_back(i);
}
vector<int>::itreator it=v.begin();
v.insert(it+2,-1);
for(;it!=v.end();it++){
printf("%d ",*it);
}
erase()用来删除vector中的元素,有两种用法,一是erase(it),删除迭代器it处的单个元素;二是erase(first, last),删除左闭右开区间[first, last)内的所有元素,例如以下代码输出1 3:
vector<int> v;
for(int i=1;i<=5;i++){
v.push_back(i);
}
vector<int>::itreator it=v.begin();
v.erase(it+1);
v.erase(it+2,it+4);
for(int i=0;i<v.size();i++){
printf("%d ",v[i]);
}
priority_queue翻译为优先队列,一般用来解决一些贪心问题,其底层是用堆来实现的。在优先队列中,任何时刻,队首元素一定是当前队列中优先级最高的那一个。使用优先队列,也必须加#include
大根堆:队首最大
priorty_queue<int> q; //默认为大顶堆优先队列
priorty_queue<int,vector<int>,less<int> > q;
小根堆
priorty_queue<int,vector<int>,greater<int> > q;
push(x)是将x加入优先队列,时间复杂度为O(log2n),n为当前优先队列中的元素个数。加入后会自动调整priority_queue的内部结构,以保证队首元素(堆顶元素)的优先级最高
top()是获取队首元素(堆顶元素),时间复杂度为O(1)。例如以下代码输出为1。
priorty_queue<int,vector<int>,greater<int> > q;//小根堆
q.push(3);
q.push(4);
q.push(1);
printf("%d\n",q.top());
pop()是让队首元素(堆顶元素)出队,由于出队后要调整堆内部结构,所以时间复杂度是O(log2n),例如:如下代码输出344。
priority_queue<int> q;
q.push(3);
q.push(4);
q.push(1);
printf("%d\n",q.size());
q.push(4);
printf("%d\n"”,q.top());
q.pop();
printf("%d\n",q.top());
map翻译为映射,其实数组就是一种映射。比如“int a[100];”,就是定义了一个int到int的映射,而“a[5]=25;”是把5映射到25,他们是一一对应的,数组总是把int类型映射到其它基本类型,因为数组下标只能是int。但有时希望把string映射成一个int,数组就不方便了这时就可以使用map,它可以将任何基本类型(包括容器)映射到任何基本类型。
使用map,也必须加#include
map<typename1, typename2> name;
其中,typename1是映射前的类型(键key),typename2是映射后的类型(值value),name为映射的名字
map<string,int> mp;
建立了一个字符串到整型的映射
使用时可以直接调用
mp['cqbzgm']=666;
printf("%d",mp['cqbzgm']);
输出为666 /手动狗头
和数组几乎一模一样,只是下标变为了定义的类型
刚才就是一个下标访问的栗子
因为map的每一对映射都有两个typename,所以使用“it -> first”来访问键,而使用“it -> second”来访问值。例如:
map<char, int> mp;
mp['m'] = 20;
mp['r'] = 30;
mp['a'] = 40;
for(map<char, int>::iterator it=mp.begin();it!=mp.end();it++){
printf("%c %d\n",it->first,it->second);
}
find(key)是返回键为key的映射的迭代器,时间复杂度为O(log2n),n为map中映射的对数
size()用来获得map中映射的对数,时间复杂度为O(1)
例如以下代码输出
3
b 30
map<char, int> mp;
mp['a'] = 20;
mp['b'] = 30;
mp['c'] = 40;
printf("%d\n", mp.size());
map<char,int>::iterator it=mp.find('b');
printf("%c %d\n",it->first,it->second);
erase()可以删除单个元素,也可以删除一个区间内的所有元素。删除单个元素可以用erase(it),其中it为要删除元素的迭代器,时间复杂度为O(1)。也可以用erase(key),key为要删除元素的键,时间复杂度为O(log2n)。 下面代码输出“a 20 c 40 ”
map<char, int> mp;
mp['a']=20;
mp['b']=30;
mp['c']=40;
map<char, int>::iterator it = mp.find('b');
mp.erase(it); //或者把上面两行改成 mp.erase(‘b’); 总时间复杂度一致
for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++){
printf("%c %d\n",it->first,it->second);
}
删除一个区间内所有元素用erase(first, last)。其中,first为区间的起始迭代器;last为区间的末尾迭代器的下一个地址,也就是左闭右开区间[first, last) 。时间复杂度为O(first - last)。 下面代码输出“a 20”
map<char, int> mp;
mp['a']=20;
mp['b']=30;
mp['c']=40;
map<char,int>::iterator it=mp.find('b');
mp.erase(it,mp.end());
for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++){
printf("%c %d\n",it->first,it->second);
}
clear()用来清空map。时间复杂度为O(n)。
pair是”二元结构体”的替代品,将两个元素捆绑在一起,节省编码时间。相当于一下定义:
struct pair {
typename1 first;
typename2 second;
};
要使用pair,必须先添加头文件,即#include
pair<typename1, typename2> name;
例如:定义一个参数为string和int类型的pair,并同时初始化:
pair<string, int> p(“haha”, 5);
pair可以直接做比较运算,比较的规则是先以first的大小作为标准,只有当first相等时才去判断second的大小。
例如:以下一段代码输出“p1 和结构体差不多。 set是一个内部自动有序且不含重复元素的容器。set最主要的作用就是自动去重并按升序排序,因此遇到需要去重但是又不方便直接开数组的情况,比如元素比较多或者类型不是int,可以尝试用set解决。set中的元素是唯一的,其内部采用“红黑树”实现。 set只能通过迭代器访问,即先定义一个迭代器: 然后使用“ insert(x)用来将x插入到set中,并自动递增排序和去重,时间复杂度为O(log2n),n为set中元素的个数。 size()用来获得set中的元素个数,时间复杂度为O(1)。 find(value)是返回set中对应值value的迭代器(可以把it看成地址,*it看成地址对应的值),时间复杂度为O(log2n)。例如以下一段代码输出“3 2”。 clear()用来清空set中的所有元素,时间复杂度为O(n)。 erase()可以删除单个元素,也可以删除一个区间内的所有元素。删除单个元素可以用erase(it),其中it为要删除元素的迭代器,时间复杂度为O(1)。也可以用erase(value),value为要删除元素的值,时间复杂度为O(log2n)。 下面代码输出“1 3 200 ” 删除一个区间内所有元素用erase(first, last)。pair<int,int> p1(5, 10);
pair<int,int> p2(5, 15);
pair<int,int> p3(10, 5);
if(p1<p3) printf("p1
访问
集合–set
概念
使用set,也必须加#include定义
set<typename> name;
访问
set<typename>::iterator it;
*it
”来访问set中的元素。Set也不支持“*(it+i)”和“itset<int> st;
st.insert(3);
st.insert(5);
st.insert(2);
st.insert(3);
for(set<int>::iterator it = st.begin(); it != st.end(); it ++){
printf("%d", *it);
}
常用函数
1.insert()
2.size()
3.find()
set<int> st;
for(int i = 1; i <= 3; i ++) st.insert(i);
printf("%d", st.size());
printf("%d", *(st.find(2)));
4.clear()
5.erase()
set<int> st;
for(int i=1;i<=3;i++){
st.insert(i);
}
st.erase(st.find(2));
for(set<int>::iterator it=st.begin(); it!=st.end();it++){
printf("%d ", *it);
}
st.clear();
st.insert(100);
st.insert(200);
st.erase(100);
for(set<int>::iterator it = st.begin(); it != st.end(); it ++){
printf("%d ", *it);
}
其中,first为区间的起始迭代器;last为区间的末尾迭代器的下一个地址,也就是左闭右开区间[first, last) 。
时间复杂度为O(first - last)。
下面代码输出“1 2 3 4 5 6 7 8 9 ”:set<int> st;
for(int i=1;i<=100;i++){
st.insert(i);
}
set<int>::iterator it=st.find(10);
st.erase(it,st.end());
for(it = st.begin(); it != st.end(); it ++){
printf("%d ", *it);
}