@[TOC](下面介绍STL中常见的容器及操作)
## 不定长数组 vector
> vetcor:其实就是一个数组或者说是容器 其操作不同于之前直接定义的数组
> 而且可以直接赋值也可以直接作为函数参数或者返回值

### 1 头文件

“`cpp
#include<vector>
“`
### 2 定义类型方法
> 可定义基本数据类型 如:int ,double,string 等
> 还可以定义指针、结构体等

“`cpp
#include <iostream>
#include <vector>
#include <cstring>
#include<algorithm>
using namespace std;
struct k{
int m,n;
};
int main()
{
vector<int>v1; //定义int类型
vector<string>v2;// 定义string 类型
vector<k>v3; //定义结构体类型
}
“`
### 3 构造方法

“`cpp
#include <iostream>
#include <vector>
#include <cstring>
#include<algorithm>
using namespace std;
int main()
{
vector<int>v1(5); //5个int类型元素 初始化为0
for(int i=0;i<5;i++)
cout<<v1[i]<<‘ ‘; //输出结果为 0 0 0 0 0

vector<int>v2(5,10);// 5个int类型元素 初始值为10
for(int i=0;i<5;i++)
cout<<v2[i]<<‘ ‘;// 输出结果为 10 10 10 10 10

vector<int>v3(v2);// 用v2初始化v3
for(int i=0;i<5;i++)
cout<<v3[i]<<‘ ‘;// 输出结果为 10 10 10 10 10

vector<int>::iterator its=v2.begin();//指向头的迭代器
vector<int>::iterator ite=v2.end();//指向尾的迭代器
vector<int>v4(its,ite);//用迭代器之间的值初始化v4
for(int i=0;i<5;i++)
cout<<v4[i]<<‘ ‘;// 输出结果为 10 10 10 10 10
}
“`
### 4 容量与大小
> **capacity**:可获取vector容量
> **reserve**:修改容量,但只能变大,不能变小
> **size**: 容器中有效元素的个数 与容量大小无关
> **resize**:改变元素个数,缩小时容量不变,放大时容量改变
> **empty**:判断容器是否为空 是空返回1 不是返回0

“`cpp
#include <iostream>
#include <vector>
#include <cstring>
#include<algorithm>
using namespace std;
int main()
{
vector<int>v1(10);
cout<<v1.capacity()<<endl;//输出结果为 10

v1.reserve(12);
cout<<v1.capacity()<<endl;//输出结果为 12
cout<<v1.size()<<endl; //输出结果为 10

v1.resize(13);
cout<<v1.size()<<‘ ‘<<v1.capacity()<<endl;//输出结果为13 20
//(增加新元素 容量超过原始容量 容量加倍)

v1.resize(6);
cout<<v1.size()<<‘ ‘<<v1.capacity()<<endl;//输出结果为 13 20
cout<<v1.empty()<<endl;//输出结果为 0

vector<int>v2;
cout<<v2.empty()<<endl;//没有元素 输出结果为 1
}
“`
### 5 主要函数

> 1.push_back 在数组的最后添加一个数据
2.pop_back 去掉数组的最后一个数据
3.at 得到编号位置的数据
4.begin 得到数组头的指针
5.end 得到数组的最后一个单元+1的指针
6.front 得到数组头的引用
7.back 得到数组的最后一个单元的引用
8.max_size 得到vector最大可以是多大
9.capacity 当前vector分配的大小
10.size 当前使用数据的大小
11.resize 改变当前使用数据的大小,如果它比当前使用的大,者填充默认值
12.reserve 改变当前vecotr所分配空间的大小
13.erase 删除指针指向的数据项
14.clear 清空当前的vector
15.rbegin 将vector反转后的开始指针返回(其实就是原来的end-1)
16.rend 将vector反转构的结束指针返回(其实就是原来的begin-1)
17.empty 判断vector是否为空
18.swap 与另一个vector交换数据

### 6 基本操作

– **输出元素**
使用下标输出元素
使用迭代器输出元素

“`cpp
#include <iostream>
#include <vector>
#include <cstring>
#include<algorithm>
using namespace std;
int main()
{
vector<int>v1(5,6);
for(int i=0;i<5;i++)
cout<<v1[i]<<endl;//下标输出

vector<int>::iterator it;//迭代器输出
for(it=v1.begin();it!=v1.end();it++)
cout<<*it<<endl;
}
“`

– **插入元素**
尾部插入元素:push_back()
中间插入元素:insert()
实际操作中 尾部插入元素效率高 中间插入效率低
“`cpp
#include <iostream>
#include <vector>
#include <cstring>
#include<algorithm>
using namespace std;
int main()
{
vector<int>v1;
for(int i=0;i<5;i++)
v1.push_back(i);//尾部插入元素
for(int i=0;i<5;i++)
cout<<v1[i]<<‘ ‘;//输出结果为 0 1 2 3 4
cout<<endl;

v1.insert(v1.begin()+1,9); // 在指定迭代器位置加入一个元素
for(int i=0;i<5;i++)
cout<<v1[i]<<‘ ‘;//输出结果为 0 9 1 2 3
cout<<endl;

v1.insert(v1.begin()+2,3,8);// 在指定迭代器后加入3个值为8的元素
vector<int>::iterator it;
for(it=v1.begin();it!=v1.end();it++)
cout<<*it<<‘ ‘;//输出结果为 0 9 8 8 8 1 2 3 4
cout<<endl;

vector<int>v2;
v2.insert(v2.begin(),v1.begin(),v1.begin()+4);//在指定迭代器后加入另一个容器的中间一段
for(int i=0;i<4;i++)
cout<<v2[i]<<‘ ‘;//输出结果为 0 9 8 8
cout<<endl;
}
“`

– **删除元素**
删除尾部元素:pop_back()
删除指定元素:erase()
删除全部元素(清空):clear()

“`cpp
#include <iostream>
#include <vector>
#include <cstring>
#include<algorithm>
using namespace std;
int main()
{
vector<int>v1;
for(int i=0;i<5;i++)
v1.push_back(i);//尾部插入元素
for(int i=0;i<5;i++)
cout<<v1[i]<<‘ ‘;//输出结果为 0 1 2 3 4
cout<<endl;

v1.pop_back();//删除尾部元素
v1.erase(v1.begin()+1);//删除第2个元素
v1.erase(v1.begin(),v1.begin()+2);//删除第1个到第3个元素
v1.clear();//删除所有元素
}
“`

– 其他函数

 

>**v.swap(v1)** 将v与v1进行交换
**front** 得到数组头的引用
**back** 得到数组的最后一个单元的引用
**max_size** 得到vector最大可以是多大
**rbegin** 将vector反转后的开始指针返回(其实就是原来的end-1)
**rend** 将vector反转构的结束指针返回(其实就是原来的begin-1)
## 集合 set
**set简介**
> set 是 STL 中一种标准关联容器,封装了一种高效的平衡检索二叉树——红黑树。
set是用来存储同一数据类型的集合,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。
标准库提供set关联容器分为:
1,按关键字有序保存元素:set(关键字即值,即只保存关键字的容器);multiset(关键字可重复出现的set);
2,无序集合:unordered_set(用哈希函数组织的set);unordered_multiset(哈希组织的set,关键字可以重复出现)。
平衡二叉检索树使用中序遍历算法,检索效率高于vector、deque和list等容器,另外使用中序遍历可将键值按照从小到大遍历出来。
构造set集合主要目的是为了快速检索,不可直接去修改键值。
当出现需要去掉重复元素的情况,而且有可能因这些元素比较大或者类型不是int 型而不能直接开散列表时,就可以用set来保留元素本身而不考虑它的个数,并且set可以自动排序;
### 1 头文件

“`cpp
#include<set>
“`
### 2 定义类型与构造方法

> 可定义基本数据类型 以及结构体等

“`cpp
#include <iostream>
#include <set>
#include <functional>
using namespace std;
int main()
{
set<int> s1; //默认是小于比较器less<int>的s1

set<int, greater<int> > s2; //创建一个带大于比较器的s2
// 需包含头文件functional
int a[5] = {1,2,3,4,5};
set<int> s3(a,a+5); //数组a初始化一个s3

set<int> s4(s3.begin(),s3.end()); //用s3区间构造s4

set<int> s5(s4); //拷贝s4构造创建s5
}

“`
### 3 主要函数

“`cpp
begin(); // 返回指向第一个元素的迭代器
end(); // 返回指向迭代器的最末尾处
clear(); // 清除所有元素
count(); // 返回某个值元素的个数
empty(); // 如果集合为空,返回true
equal_range(); //返回集合中与给定值相等的上下限的两个迭代器
erase(); //删除集合中的元素
find(); //返回一个指向被查找到元素的迭代器
get_allocator(); //返回集合的分配器
insert(); //在集合中插入元素
lower_bound(); //返回指向大于(或等于)某值的第一个元素的迭代器
upper_bound(); //返回大于某个值元素的迭代器
key_comp(); //返回一个用于元素间值比较的函数
max_size(); //返回集合能容纳的元素的最大限值
rbegin(); //返回指向集合中最后一个元素的反向迭代器
rend(); //返回指向集合中第一个元素的反向迭代器
size(); //集合中元素的数目
swap(); //交换两个集合变量
value_comp(); //返回一个用于比较元素间的值的函数
“`
### 4 基本操作
– **添加与访问元素**

“`cpp
#include <iostream>
#include <set>
#include <functional>
using namespace std;
int main()
{
set<int>s1={4,5,6,7};
s1.insert(2);
s1.insert(5);
cout<<s1.size()<<endl;//结果为5 可以发现set中无重复元素
set<int>::iterator it;//set只能通过迭代器输出 无法用下标输出
for(it=s1.begin();it!=s1.end();it++)
cout<<*it<<‘ ‘;//结果为 2 4 5 6 7
cout<<endl;
}

“`

– **查找元素**

“`cpp
#include <iostream>
#include <set>
#include <functional>
using namespace std;
int main()
{
set<int>s1={4,5,6,7};
s1.insert(2);
s1.insert(5);
set<int>::iterator it;
it=s1.find(4);// 返回set中值为x的迭代器 如果找不到x就返回end()
if(it!=s1.end()) cout<<1<<endl;
else cout<<0<<endl;//找到了输出结果为 1

int cnt=s1.count(5);//count 用来查找某个键值出现的次数(0或者1)
cout<<cnt<<endl;//输出结果为 1
cnt=s1.count(10);
cout<<cnt<<endl;//输出结果为 0

it=s1.lower_bound(5);//返回 set 中大于等于 x 的最小元素的迭代器
cout<<*it<<endl;//输出结果为 5
//如果找不到会返回 end() 的迭代器

it=s1.upper_bound(5);//返回 set 中大于 x 的最小元素的迭代器
cout<<*it<<endl;//输出结果为 6
}

“`
– **删除元素**
“`cpp
#include <iostream>
#include <set>
#include <functional>
using namespace std;
int main()
{
set<int>s1={4,5,6,7};
s1.insert(2);
s1.insert(5);
set<int>::iterator it;
s1.erase(7);//删除单个元素
for(it=s1.begin();it!=s1.end();it++)
cout<<*it<<‘ ‘;//输出结果为 2 4 5 6
cout<<endl;

s1.erase(s1.begin(),s1.find(5));//删除一个区间内的所有元素
for(it=s1.begin();it!=s1.end();it++)
cout<<*it<<‘ ‘;//输出结果为 5 6
cout<<endl;

s1.clear();//清空set中所有元素
cout<<s1.empty()<<endl;// 结果为1 说明为空
}

“`

– **关于排序**

非结构体类型

“`cpp
#include <iostream>
#include <set>
#include <functional>
using namespace std;
struct cmp
{
bool operator()(const int &a,const int &b)
{return a>b;}//降序
};
int main()
{
set<int>s1={4,5,6,7,1,3,9};
set<int>::iterator it;
for(it=s1.begin();it!=s1.end();it++)
cout<<*it<<‘ ‘;//set中默认升序 输出结果为 1 3 4 5 6 7 9
cout<<endl;

set<int,greater<int> >s;//实现降序排序
for(int i=5;i<=9;i++)
s.insert(i);
set<int>::iterator x;
for(x=s.begin();x!=s.end();x++)
cout<<*x<<‘ ‘;//输出结果为 9 8 7 6 5
cout<<endl;

set<int,cmp>s2={0,5,3,4,9,6};//通过构造实现降序排序
set<int,cmp>::iterator x1;
for(x1=s2.begin();x1!=s2.end();x1++)
cout<<*x1<<‘ ‘;//输出结果为 9 6 5 4 3 0
cout<<endl;
}

“`

结构体类型

“`cpp
#include <iostream>
#include <set>
#include <functional>
using namespace std;
struct sss
{
int a,b;
// 结构体插入set中 需要重载'<‘运算符 从而实现降序排序
bool operator<(const sss &x)const
{
if(x.a==a) return b<x.b;
else return a>x.a;
}
};
int main()
{
set<sss>a;
set<sss>::iterator it;
sss x1={5,8};
sss x2={5,3};
sss x3={4,7};
sss x4={8,1};
a.insert(x1);a.insert(x2);a.insert(x3);a.insert(x4);
for(it=a.begin();it!=a.end();it++)
cout<<(*it).a<<‘ ‘<<(*it).b<<endl;//输出结果为 8,1 5,3 5,8 4,7
}

“`

版权声明:本文为jojoqiao原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/jojoqiao/p/14489921.html