【总结】2020暑假集训--STL

目录

  • 不定长数组--vector
    • 概念:
    • 定义:
    • 访问
      • 下标访问
      • 迭代器访问
    • 常用函数
      • 1.push_back()
      • 2.size()
      • 3.pop_back()
      • 4.clear()
      • 5.insert()
      • 6.erase()
  • 优先队列--priority_queue
    • 概念
    • 定义
    • 常用函数
      • 1.push()
      • 2.top()
      • 3.pop()
  • 映射--map
    • 概念
    • 定义
    • 访问
      • 下标访问
      • 迭代器访问
    • 常用函数
      • 1.find()
      • 2.size()
      • 3.erase()
      • 4.clear()
  • 二元结构体--pair
    • 概念
    • 定义
    • 初始化
    • 访问
  • 集合--set
    • 概念
    • 定义
    • 访问
    • 常用函数
      • 1.insert()
      • 2.size()
      • 3.find()
      • 4.clear()
      • 5.erase()

不定长数组–vector

概念:

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 v; 表示定义了一个数据类型为int,名为v的不定长数组

其中typename也可以是一个STL容器

vector<vector<int> > a;  //定义了一个两个维度都可变的二维整型数组a 

注意vector> > 这里两个>之间一定要加空格,不然编译器会误认为是位运算的左移符号“>>”

访问

访问vector中的元素一般有两种方式:下标访问 和 迭代器(iterator)访问

下标访问

对于容器vector v,可以使用v[index]来访问它的第index个元素。其中,0≤index≤v.size() – 1,v.size()表示vector中元素的个数。

迭代器访问

可以将迭代器理解为一种类似指针的变量,使用前需要提前定义,其定义为:vector::iterator it,这个it就是一个迭代器,可以通过“*it”来访问该容器里的元素值:

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);
}

常用函数

1.push_back()

push_back(x)将x添加到容器最后,并相应让长度+1,时间复杂度为 O ( 1 ) O(1) O(1)

2.size()

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]);
}

3.pop_back()

用来删除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]);
}

4.clear()

用来清空vector中的所有元素。时间复杂度为O(n),例如以下代码输出0:

vector<int> v;
for(int i=1;i<=3;i ++){
	v.push_back(i);
}
v.clear();
printf("%d",v.size());

5.insert()

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);
}

6.erase()

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

概念

priority_queue翻译为优先队列,一般用来解决一些贪心问题,其底层是用堆来实现的。在优先队列中,任何时刻,队首元素一定是当前队列中优先级最高的那一个。使用优先队列,也必须加#include及using namespace std;。

定义

大根堆:队首最大

priorty_queue<int> q;            //默认为大顶堆优先队列
priorty_queue<int,vector<int>,less<int> > q;

小根堆

priorty_queue<int,vector<int>,greater<int> > q;

常用函数

1.push()

push(x)是将x加入优先队列,时间复杂度为O(log2n),n为当前优先队列中的元素个数。加入后会自动调整priority_queue的内部结构,以保证队首元素(堆顶元素)的优先级最高

2.top()

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());

3.pop()

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

概念

map翻译为映射,其实数组就是一种映射。比如“int a[100];”,就是定义了一个int到int的映射,而“a[5]=25;”是把5映射到25,他们是一一对应的,数组总是把int类型映射到其它基本类型,因为数组下标只能是int。但有时希望把string映射成一个int,数组就不方便了这时就可以使用map,它可以将任何基本类型(包括容器)映射到任何基本类型。
使用map,也必须加#include及using namespace std;

定义

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);
}

常用函数

1.find()

find(key)是返回键为key的映射的迭代器,时间复杂度为O(log2n),n为map中映射的对数

2.size()

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);

3.erase()

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);
}

4.clear()

clear()用来清空map。时间复杂度为O(n)。

二元结构体–pair

概念

pair是”二元结构体”的替代品,将两个元素捆绑在一起,节省编码时间。相当于一下定义:

struct pair {
       typename1 first;
       typename2 second;
};

定义

要使用pair,必须先添加头文件,即#include,同时需要using namespace std;。因为map的内部实现涉及pair,因此添加map头文件时会自动添加utility头文件,此时可以省去utility头文件。

pair<typename1, typename2> name;

初始化

例如:定义一个参数为string和int类型的pair,并同时初始化:

pair<string, int> p(“haha”, 5);       

pair可以直接做比较运算,比较的规则是先以first的大小作为标准,只有当first相等时才去判断second的大小。

例如:以下一段代码输出“p1

pair<int,int> p1(5, 10);
pair<int,int> p2(5, 15);
pair<int,int> p3(10, 5);
if(p1<p3) printf("p1);
if(p1<=p3) printf("p1<=p3");
if(p1<p2) printf("p1);

访问

和结构体差不多。

集合–set

概念

set是一个内部自动有序且不含重复元素的容器。set最主要的作用就是自动去重并按升序排序,因此遇到需要去重但是又不方便直接开数组的情况,比如元素比较多或者类型不是int,可以尝试用set解决。set中的元素是唯一的,其内部采用“红黑树”实现。
使用set,也必须加#include及using namespace std;

定义

set<typename> name;

访问

set只能通过迭代器访问,即先定义一个迭代器:

set<typename>::iterator it;

然后使用“*it”来访问set中的元素。Set也不支持“*(it+i)”和“it

set<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()

insert(x)用来将x插入到set中,并自动递增排序和去重,时间复杂度为O(log2n),n为set中元素的个数。

2.size()

size()用来获得set中的元素个数,时间复杂度为O(1)。

3.find()

find(value)是返回set中对应值value的迭代器(可以把it看成地址,*it看成地址对应的值),时间复杂度为O(log2n)。例如以下一段代码输出“3 2”。

set<int> st;
for(int i = 1; i <= 3; i ++) st.insert(i);
printf("%d", st.size());
printf("%d", *(st.find(2)));

4.clear()

clear()用来清空set中的所有元素,时间复杂度为O(n)。

5.erase()

erase()可以删除单个元素,也可以删除一个区间内的所有元素。删除单个元素可以用erase(it),其中it为要删除元素的迭代器,时间复杂度为O(1)。也可以用erase(value),value为要删除元素的值,时间复杂度为O(log2n)。 下面代码输出“1 3 200 ”

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);
}

删除一个区间内所有元素用erase(first, last)。
其中,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);
}

你可能感兴趣的:(STL,总结)