放一张目录图吧,方便按需查找。
STL之sort函数
时间复杂度是n*log2(n)
sort(begin,end);
sort(begin,end,cmp);
升序模式(默认)
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[10];
for(int i=0;i<10;i++)
{
a[i]=rand()%100;
}
sort(a,a+10);//左闭右开,默认升序
for(int i=0;i<10;i++)
{
cout<<a[i]<<' ';
}
return 0;
}
降序模式
1、加入greater();//greater<类型>()将大的放在前面
sort(a,a+10,greater<int>());
2、运用reverse(a,a+n)方法反转,sort默认升序,再用reverse反转,就成了降序
自定义模式
如果想按照自己的想法排序,如按绝对值降序
#include<bits/stdc++.h>
using namespace std;
bool cmp(int a,int b)//cmp是自己控制的方法
{
return abs(a)>abs(b);
}
int main(){
int a[10];
for(int i=0;i<10;i++)
{
a[i]=rand()%100-50;
}
sort(a,a+10,cmp);//函数提供第三个参数cmp使使用者按自己想法调用
for(int i=0;i<10;i++)
{
cout<<a[i]<<' ';
}
return 0;
}
STL之unique函数
unique函数属于STL中比较常用函数,它的功能是元素去重。unique函数的去重过程实际上就是不停的把后面不重复的元素移到前面来,由于它”删除”的是相邻的重复元素,所以在使用unique函数之前,一般都会将目标序列进行排序。
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[6]={1,3,3,2,2,2};
sort(a,a+6);//先排序
//unnique返回的是指针,指向最后一个不重复位置的下一个位置
int num=unique(a,a+6)-a;//用num 来接受有多少个不重复数据
for(int i=0;i<num;i++)
{
cout<<a[i]<<' ';
}
return 0;
}
STL之二分查找函数
二分查找要求数组递增;
binary_search
: 查找某个元素是否出现
a.函数模板:
binary_search(arr,arr+size,indx)
b.参数说明:
arr: 数组首地址
size:数组元素个数
indx: 需要查找的值
c.函数功能:
在数组中以二分法检索的方式查找,若在数组(要求数组元素非递减)中查找到indx元素则真,若查找不到则返回值为假。
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[6]={1,2,3,2,2,2};
sort(a,a+6);
cout<<binary_search(a,a+6,3);//1
return 0;
lower_bound
:查找第一个大于或等于某个元素的位置。
a.函数模板:
lower_bound(arr[],arr[]+size , indx):
b.参数说明:
arr[]: 数组首地址
size:数组元素个数
indx: 需要查找的值
c.函数功能:
函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置(注意是地址)。如果所有元素都小于val,则返回last的下一位置
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[6]={1,2,3,2,2,2};
sort(a,a+6);//[1,2,2,2,2,3]
int cont=lower_bound(a,a+6,3)-a;//得到索引位
cout<<cont;//5
return 0;
}
upper_bound:
查找第一个大于某个元素的位置。
a.函数模板:
upper_bound(arr[],arr[]+size , indx):
b.参数说明:
arr[]: 数组首地址
size:数组元素个数
indx:需要查找的值
c.函数功能:
函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val的第一个元素位置
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[6]={1,2,3,2,2,2};
sort(a,a+6);//[1,2,2,2,2,3]
int cont=upper_bound(a,a+6,2)-a;
cout<<cont;//5
return 0;
}
STL之vector容器
构造函数
1、创建一个int类型的空的vector对象:
vector<int> v;
2、创建一个包含500个Widget类型数据的vector:
vector<Widget> vWidgets(500);
3、创建一个包含500个Widget类型数据的vector:
vector<Widget> vWidgets(500);
4、创建一个包含25个char类型数据的vector,并将它们全部初始化为 ‘A’
vector<char> letters (25, 'A');
begin()函数与end() 函数
begin()函数的作用为取vi的首元素地址。end() 函数取的是尾元素地址的下一个地址。(左闭右开)
front()函数和back()函数
front()函数返回第一个元素,back函数,返回最后一个元素.
push_back()函数
push_back()函数表示将数据添加到vector的尾部,并按需要来分配内存。
pop_back()函数
pop_back()用于删除vector的尾元素
insert()函数
insert(v.begin()+inx,x)用来向vector的任意迭代器inx处插入一个元素X
erase()函数
1、删除单个元素。erase(it)即删除迭代器为it处的元素。
2、删除一个区间内的所有元素。erase(frist, last)即删除[frist, last) 内的所有元素。
at(idx)函数
传回索引idx所指的数据,如果idx越界,抛出out_of_range。
empty()函数
判断容器是否为空,不为空则返回0,否则返回1;
迭代器 iterator
定义一个迭代器:
vector<int>::iterator it;
for(it=v.begin();it!=v.end();it++){
cout<<*it<<endl;//取it对应的元素
}
实际操作
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int> v;//定义一个容器
v.push_back(1); //插入数据 v[0]=1
v.push_back(2); //v[1]=2
v.push_back(3); //v[2]=3
v.push_back(7);
v.push_back(5);
for(int i=0;i<v.size();i++){//v.size()获取容器元素个数
cout<<v[i]<<" ";//v[i]获取某位置的数据值
}
v.pop_back();//删除容器末尾的数据
cout<<v.size()<<endl;
v.insert(v.begin(),5);//在0位置处插入 元素5
for(int i=0;i<v.size();i++){
cout<<v[i]<<" ";
}
v.erase(v.begin());
for(int i=0;i<v.size();i++){
cout<<v[i]<<" ";
}
cout<<v.at(1)<<endl;//at()函数获取索引处的数据
cout<<v.empty()<<endl;//判断容器是否为空
cout<<"第一个元素:"<<v.front()<<endl;
cout<<"最后一个元素:"<<v.back()<<endl;
vector<int>::iterator it;//定义迭代器
for(it=v.begin();it!=v.end();it++){
cout<<*it<<endl;//取it对应的元素
}
//可以用数组方法修改vector的值,
// 但不可以在vector未开辟内存前使用
v[1]=100;
for(int i=0;i<v.size();i++){
cout<<v[i]<<" ";
}
sort(v.begin(),v.end());//升序排序
for(int i=0;i<v.size();i++){
cout<<v[i]<<" ";
}
return 0;
STL之String容器
构造函数
1、生成一个空字符串s
string s;
2、拷贝构造函数生成str的复制品
string s(str);
3、生成一个字符串,包含n个c字符
string s(n,c) ;
4、以区间begin():end() (不包含end())内的字符作为字符串s的初值
string s(str.begin(),str.end()) ;
push_back()函数
在字符串末尾插入字符
s1.push_back('a');
append()函数
字符串拼接
s1.append(s2);//在s1后拼接s2,并返回给s1;
insert()函数
在字符串的索引位置前插入字符
s1.insert(s1.begin()+3,'s');
size()函数
返回字符串字符个数
遍历方式
1、数组方式
for(int i=0;i<s1.size();i++){
cout<<"第"<<i+1<<"个字符:"<<s1[i]<<endl;
}
2、迭代器方式
正向遍历
string::iterator it;
for(it=s1.begin();it!=s1.end();it++)
{
cout<<*it<<" ";
}
反向遍历
string::reverse_iterator rit;//反向迭代器
for(rit=s1.rbegin();rit!=s1.rend();rit++)
{
cout<<*rit<<" ";
}
erase()函数
1)iterator erase(iterator p);
删除字符串中p所指的字符
s1.erase(s1.begin()+2);//删除索引为2处的元素
2)iterator erase(iterator first, iterator last);
删除字符串中迭代器区间[first,last)上所有字符,包前不包后
s1.erase(s1.begin(),s1.begin()+2);//删除索引[0,2)的元素
3)string& erase(size_t pos = 0, size_t len = npos);
删除字符串中从索引位置pos开始的len个字符
s1.erase(0,2);//删除索引[0,2)的元素
replace() 函数
1)string& replace(size_t pos, size_t n, const char *s);
将当前字符串从pos索引开始的n个字符,替换成字符串s
s1.replace(2,2,s2);//将s1字符串从2索引开始的2个字符,替换成字符串s2
2)string& replace(size_t pos, size_t n, size_t n1, char c);
将当前字符串从pos索引开始的n个字符,替换成n1个字符c
s1.replace(2,5,3,'d');//将s1字符串从2索引开始的5个字符,替换成3个字符 'd'
3)string& replace(iterator i1, iterator i2, const char* s);
将当前字符串[i1,i2)区间中的字符串替换为字符串s
s1.replace(s1.begin()+2,s1.begin()+5,"bbb");//将s1字符串[2,5)区间中的字符串替换为字符串"bbb"
find()函数
1)size_t find (constchar* s, size_t pos = 0) const;
在当前字符串的pos索引位置开始,查找子串s,返回找到的位置索引,-1表示查找不到子串
cout<<s1.find("aa",0);//从索引0开始查找子串"aa" ,返回找到的索引位置0
2)size_t find (charc, size_t pos = 0) const;
在当前字符串的pos索引位置开始,查找字符c,返回找到的位置索引,-1表示查找不到字符
cout<<s1.find('b',0)<<endl;//从索引0开始查找子串'b' ,返回找到的索引位置 2
rfind()函数
1)size_t rfind (constchar* s, size_t pos = npos) const;
//在当前字符串的pos索引位置开始,反向查找子串s,返回找到的位置索引,-1表示查找不到子串
cout<<s1.rfind("aa",s1.size())<<endl;//从索引0开始查找子串"aa" ,返回找到的索引位置 0
2)size_t rfind (charc, size_t pos = npos) const;
//在当前字符串的pos索引位置开始,反向查找字符c,返回找到的位置索引,-1表示查找不到字符
cout<<s1.rfind('b',s1.size())<<endl;//从索引0开始查找子串'b' ,返回找到的索引位置 4
compare() 函数
compare函数比的是ASCII码,从第一位开始逐位比较,如bb>aaa,不看位数
1)int compare (conststring& str) const;
将当前字符串与字符串str比较,相等返回0,大于str返回1,小于str返回-1
cout<<s1.compare(s2)<<endl;//s1与s2比较,大于返回1 s1="aabbbd" s2="aaaaa"
cout<<s1.compare(s1)<<endl;//s1与s2比较,等于返回0
cout<<s2.compare(s1)<<endl;//s2与s1比较,小于返回-1
2)int compare (size_tpos, size_t len, const char* s) const;
将当前字符串从Pos索引位置开始的len个字符构成的字符串与字符串s比较,相等返回0,大于str返回1,小于str返回-1
cout<<s1.compare(2,3,s2)<<endl;//从s1的2索引位开始的3位字符串,与s2比较,大于返回1
实际操作
#include<bits/stdc++.h>
using namespace std;
int main(){
string s1;//生成空字符串
string s2(5,'a');//生成一个字符串,包含5个a字符
cout<<s2<<endl;
string s3(s2);//拷贝构造函数生成s2的复制品
cout<<s3<<endl;
string s4(s3.begin(),s3.begin()+3);//以区间begin()~3 (不包含3)内的字符作为字符串s的初值
cout<<s4<<endl;
s1.push_back('b');//在末尾插入字符
cout<<s1<<endl;
s1.append(s2);//在s1后拼接s2,并返回给s1;
cout<<s1<<endl;
s1.insert(s1.begin()+3,'s');//在索引位为3处插入 s 字符
cout<<s1<<endl;
cout<<"s1中字符个数:"<<s1.size()<<endl;
for(int i=0;i<s1.size();i++){
cout<<"第"<<i+1<<"个字符:"<<s1[i]<<endl;
}
string::iterator it;//迭代器
for(it=s1.begin();it!=s1.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
string::reverse_iterator rit;//反向迭代器
for(rit=s1.rbegin();rit!=s1.rend();rit++)
{
cout<<*rit<<" ";
}
s1.erase(s1.begin()+2);//删除索引为2处的元素
cout<<s1<<endl;
s1.erase(s1.begin(),s1.begin()+2);//删除索引[0,2)的元素
cout<<s1<<endl;
s1.erase(0,2);//删除索引[0,2)的元素
cout<<s1<<endl;
s1.push_back('b');
s1.push_back('c');
s1.push_back('d');
cout<<"S1:"<<s1<<endl;//aa bcd
cout<<"S2:"<<s2<<endl;//aa aaa
s1.replace(2,2,s2);//将s1字符串从2索引开始的2个字符,替换成字符串s2
cout<<"S1:"<<s1<<endl;//aa aaaaa d
s1.replace(2,5,3,'c');//将s1字符串从2索引开始的5个字符,替换成3个字符 'c'
cout<<"S1:"<<s1<<endl;//aa ccc d
s1.replace(s1.begin()+2,s1.begin()+5,"bbb");//将s1字符串[2,5)区间中的字符串替换为字符串"bbb"
cout<<"S1:"<<s1<<endl;//aa bbb d
cout<<s1.find("aa",0)<<endl;//从索引0开始查找子串"aa" ,返回找到的索引位置 0
cout<<s1.find('b',0)<<endl;//从索引0开始查找子串'b' ,返回找到的索引位置 2
cout<<s1.rfind("aa",s1.size())<<endl;//从索引0开始查找子串"aa" ,返回找到的索引位置 0
cout<<s1.rfind('b',s1.size())<<endl;//从索引0开始查找子串'b' ,返回找到的索引位置 4
cout<<s1.compare(s2)<<endl;//s1与s2比较,大于返回1
cout<<s1.compare(s1)<<endl;//s1与s2比较,等于返回0
cout<<s2.compare(s1)<<endl;//s2与s1比较,小于返回-1
cout<<s1.compare(2,3,s2)<<endl;//从s1的2索引位开始的3位字符串,与s2比较,大于返回1
return 0;
}
STL之queue适配器
队列,简称对,是一种操作受限的线性表。限制为:只允许在队首删除(出队),队尾插入(入队),其特点是先进先出。在STL中,queue作为一种适配器,其底层容器一般为deque(双端队列)和list(双向链表),其中deque为默认底层容器。
构造函数
模板:queue<数据类型,容器类型> q;
数据类型:可以是int、double等基本类型,也可以是自定义的结构体。
容器类型:一般为deque(双端列队)或者list(双向链表),可省略,省略时以deque为默认容器
queue<int> q;//默认使用deque(双端队列)为底层容器创建一个空的队列对象,元素类型为int
queue<int> q1[10];//创建一个10元素队列
push()函数
将元素从队尾插入
for(int i=0;i<5;i++){
q.push(i+1);//在队尾插入元素 1 2 3 4 5
}
pop()函数
删除队首元素 。
q.pop();//队首元素1 出队 2 3 4 5
size()函数
返回队列元素个数
cout<<q.size()<<endl;//输出队列元素个数4
front()函数
返回队首元素
cout<<q.front()<<endl;//返回队首元素2
back()函数
cout<<q.back()<<endl;//返回队尾元素5
empty()函数
判断队列是否为空,空返回1,非空返回0;
cout<<q.empty()<<endl;//非空返回0
实际操作
#include<bits/stdc++.h>
using namespace std;
int main(){
queue<int> q;//默认使用deque(双端队列)为底层容器创建一个空的队列对象,元素类型为int
queue<int> q1[10];//创建一个10元素队列
for(int i=0;i<5;i++){
q.push(i+1);//在队尾插入元素 1 2 3 4 5
}
q.pop();//队首元素1 出队 2 3 4 5
cout<<q.size()<<endl;//输出队列元素个数4
cout<<q.front()<<endl;//返回队首元素2
cout<<q.back()<<endl;//返回队尾元素5
cout<<q.empty()<<endl;//非空返回0
while(!q.empty()){//队列遍历
cout<<q.front()<<" ";
q.pop();
}
return 0;
}
STL之priority_queue适配器
优先队列是一种会按照默认或自定义的优先级进行自动排序的队列,其特点是优先级高的元素排在队首,低的排在队尾。头文件#include< queue > 中提供了两种可直接引用的优先规则(排序规则):greater、less;其中,less是默认优先规则,表示数字大的优先级大(字符型用ASCLL码比较),放在队首;greater表示数字小的优先级大,放在队首。
注意:sort()中 默认数字小优先级大
构造函数
模板:priority_queue< 数据类型,容器类型,优先规则> pq;
数据类型:可以是int、double等基本类型,也可以是自定义的结构体。
容器类型:一般为deque(双端列表)、vector(向量容器),可省略,省略时以vector为默认容器。
与queue区别
常用函数如push()、pop()、size()、empty()一样操作,多了一个top()函数,没有front()、back()函数
top()
返回堆顶元素
cout<<pq.top()<<" ";//返回堆顶元素
实际操作
#include<bits/stdc++.h>
using namespace std;
int main(){
priority_queue<int> pq;
//默认以vector容器、less排序规则(从大到小) 创建一个int类型的优先队列
pq.push(1);//在队尾插入元素
pq.push(5);
pq.push(3);
while(!pq.empty()){//判断是否为空,空则返回1,非空返回0
cout<<pq.top()<<" ";//返回堆顶元素
pq.pop();//删除堆顶元素
}
cout<<endl;
priority_queue<int,vector<int>,greater<int> > q;
//以vector为容器、greater排序规则(从小到大)创建一个int类型的优先队列
q.push(1);
q.push(5);
q.push(3);
while(!q.empty()){
cout<<q.top()<<" ";
q.pop();
}
return 0;
}
STL之deque适配器
容器deque和vector非常相似,属于序列式容器。都是采用动态数组来管理元素,提供随机存取,并且有着和vector一样的接口。不同的是deque具有首尾两端进行快速插入、删除的能力。底层是一个双向链表。
构造函数
deque c;
创建一个空的deque
deque c1(c2);
复制deque,复制跟c1一模一样的队列c2
deque c(n);
创建一个deque,元素个数为n,且值均为0
deque c(n,num);
创建一个deque,元素个数为n,且值均为num
deque<int> c1(5,2);//直接创建一个有5个都为1元素的队列
迭代器
deque::iterator it;
正向迭代器
deque<int>::iterator it;;//创建一个正向迭代器
for(it=c.begin();it!=c.end();it++){//正向遍历队列c
cout<<*it<<" ";
}
deque::reverse_iterator rit;
逆向迭代器
deque<int>::reverse_iterator rit;//创建一个反向迭代器
for(rit=c1.rbegin();rit!=c1.rend();rit++){//反向遍历队列c1
cout<<*rit<<" ";
}
元素添加
push_back()
在容器尾部添加一个数据
c2.push_back(5);
push_front()
在容器头部插入一个数据
c2.push_front(6);
元素修改
pop_back()
删除容器最后一个数据
c2.pop_back();//删除队尾元素
pop_front()
删除容器第一个数据
c2.pop_front();//删除队头元素
数据存取
at(idx)
返回索引下标idx所指的数据(从0开始)
cout<<c2.at(2);//返回索引为2的元素,2
front()
返回第一个数据
cout<<c2.front()<<endl;//返回队首元素,7
back()
返回最后一个数据
cout<<c2.back()<<endl;//返回队尾元素 4
迭代指针
begin()和end()函数
返回指向第一个数据的迭代器,返回指向最后一个数据的下一个位置的迭代器
rbegin()和 rend()函数
返回逆向队列的第一个数据, 返回指向逆向队列的最后一个数据的下一个位置的迭代器
大小&非空判断
size()
返回容器中元素的个数
cout<<c2.size()<<endl;//返回序列元素个数 6
empty()
判断容器是否为空
cout<<c2.empty()<<endl;//判断序列是否为空,非空返回0
实际操作
#include<bits/stdc++.h>
using namespace std;
int main(){
deque<int> c;//创建一个空的双端队列
c.assign(5,1);//初始化队列c为5个元素都为1的队列
//上述两部可合为一个
deque<int> c1(5,2);//直接创建一个有5个都为2元素的队列
deque<int>::iterator it;;//创建一个正向迭代器
for(it=c.begin();it!=c.end();it++){//正向遍历队列c
cout<<*it<<" ";
}
cout<<endl;
deque<int>::reverse_iterator rit;//创建一个反向迭代器
for(rit=c1.rbegin();rit!=c1.rend();rit++){//反向遍历队列c1
cout<<*rit<<" ";
}
cout<<endl;
deque<int> c2;
c2.push_back(5);//在队尾添加元素
c2.push_back(2);
c2.push_back(9);
c2.push_back(3);
c2.push_back(4);
c2.push_back(8);
c2.push_front(7);//在队头添加元素
c2.push_front(6);
for(it=c2.begin();it!=c2.end();it++){//正向遍历队列c
cout<<*it<<" ";
}
cout<<endl;
c2.pop_back();//删除队尾元素
c2.pop_front();//删除队头元素
for(it=c2.begin();it!=c2.end();it++){//正向遍历队列c
cout<<*it<<" ";
}
cout<<endl;
cout<<c2.at(2)<<endl;//返回索引为2的元素,2
cout<<c2.front()<<endl;//返回队首元素,7
cout<<c2.back()<<endl;//返回队尾元素 4
cout<<c2.empty()<<endl;//判断序列是否为空,非空返回0
cout<<c2.size()<<endl;//返回序列元素个数 6
return 0;
}
STL之stack容器
数据结构栈,后进先出
成员函数
empty()
堆栈为空则返回真
pop()
移除栈顶元素
push()
在栈顶增加元素
size()
返回栈中元素数目
top()
返回栈顶元素
实际操作
#include<bits/stdc++.h>
using namespace std;
int main(){
stack<int> s;//构建空栈
s.push(3);//在栈顶压入元素
s.push(4);
s.push(1);
s.push(7);
s.push(9);
cout<<s.top()<<endl;//返回栈顶元素
cout<<s.size()<<endl;//返回栈元素个数 5
while(!s.empty()){//非空则为0
cout<<s.top()<<" ";
s.pop();//移除栈顶元素
}
return 0;
}
STL之merge函数
merge函数的作用是:将两个已经排好序的序列合并为一个有序的序列。
构造函数
merge(first1,last1,first2,last2,result,compare);
firs1t为第一个容器的首迭代器,last1为第一个容器的末迭代器;
first2为第二个容器的首迭代器,last2为容器的末迭代器;
result为存放结果的容器,comapre为比较函数(可略写,默认为合并为一个升序序列)
注意
使用的时候result,如果用的vector,必须先resize一下
实际操作
vector容器
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int> a,b,c;
a.push_back(3);
a.push_back(4);
a.push_back(1);
a.push_back(8);
sort(a.begin(),a.end());
b.push_back(3);
b.push_back(7);
b.push_back(6);
b.push_back(2);
sort(b.begin(),b.end());
c.resize(8);//重新指定容器长度为8
merge(a.begin(),a.end(),b.begin(),b.end(),c.begin());//序列合并
for(int i=0;i<c.size();i++){
cout<<c[i]<<" ";
}
return 0;
}
数组
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[4]={3,7,5,2};
int b[6]={1,9,8,6,4,10};
sort(a,a+4);//2 3 5 7
sort(b,b+6);//1 4 6 8 9 10
int c[10];
merge(a,a+4,b,b+6,c);//合并数组
for(int i=0;i<10;i++){
cout<<c[i]<<" ";//1 2 3 4 5 6 7 8 9 10
}
return 0;
}
STL之find函数和count函数
find用于查找指定数据在某个区间中是否存在,该函数返回等于指定值的第一个元素位置,如果没有找到就返回最后元素位置;count用于统计某个值在指定区间出现的次数,
find()函数
find(begin,end,value);
count()函数
count(begin,end,value);
实际操作
#include<bits/stdc++.h>
using namespace std;
bool cmp(int a,int b){
return a<b;
}
int main(){
int a[10]={1,2,2,3,4,5,7,9,9,10};
int *ptr=find(a,a+10,0);//查询不到0.返回10位置的后一个位置
int idx=ptr-a;//得到索引位置
cout<<idx<<endl;
int num=count(a,a+10,9);//查询9出现2次
cout<<num;
return 0;
}
STL之pair方法
类模板:template <class T1, class T2> struct pair
参数:T1是第一个值的数据类型,T2是第二个值的数据类型。
功能:pair将一对值组合成一个值,这一对值可以具有不同的数据类型(T1和T2),两个值可以分别用pair的两个公有函数first和second访问。
构造
pair<int,string> p1;//默认构造函数
pair<int,double> p2(2,3.3);//给定初值初始化
pair<int,double> p3(p2);//拷贝构造函数
数据访问
cout<<p3.first<<endl;//first访问第一个数据
cout<<p3.second<<endl;//second访问第二个数据
数据修改
p1.first=5;
p2.second=8.2;
p3=make_pair(1,2.5);
实际操作
#include<bits/stdc++.h>
using namespace std;
int main(){
pair<int , string> p1;//默认构造函数
pair<int,double> p2(2,3.3);//给定初值初始化
pair<int,double> p3(p2);//拷贝构造函数
p1.first=5;
p2.second=8.2;
cout<<p3.first<<endl;//first访问第一个数据
cout<<p3.second<<endl;//second访问第二个数据
p3=make_pair(1,2.5);
cout<<p3.first<<endl;//first访问第一个数据
cout<<p3.second<<endl;//second访问第二个数据
return 0;
}
STL之set容器
set内部采用平衡检索二叉树:红黑树,在set中查找用的是二分查找,所有时间复杂度为O(log n).
(1)set是STL中一个很有用的容器,用来存储同一种数据类型的数据结构(可以称之为K的模型),基本功能与数组相似。
(2)set与数组不同的是,在set中每个元素的值都是唯一的。
(3)而且set插入数据时,能够根据元素的值自动进行排序。
(4)set中数元素的值并不能直接被改变。
构造函数
set<类型> s;
set< int> s;//默认构造函数
元素添加
insert(value);
当value已经存在时,不会再添加进去
s.insert(2);//添加元素
insert (iterator position, val);
在指定迭代器位置上插入函数
元素删除
O(log n)
erase(iterator);删除迭代器所指元素
erase(first,second),删除定位器first和second之间的值
erase(value),删除键值value的值
s.erase(s.begin());//删除元素4
for(it=s.begin();it!=s.end();it++){//遍历
cout<<*it<<" ";//结果 4 5 7
}
元素查询
O(log n)
find(value);查找value位置,存在返回iterator,不存在返回end();
cout<<endl<<*s.find(5)<<endl;//find()查找存在返回interator,没有则返回end();
lower_bound()和upper_bound()
可以用这两个函数划分出区间进行元素遍历
set<int>::iterator itlow=s.lower_bound(3);//指向第一个大于或等于3的位置
set<int>::iterator itup=s.upper_bound(6);//指向第一个大于6的位置
for(it=itlow;it!=itup;it++){//遍历[3,6]区间的元素
cout<<*it<<" ";//4 5
}
begin()与end()函数
返回正向迭代器
set<int>::iterator it;//迭代器
for(it=s.begin();it!=s.end();it++){//遍历
cout<<*it<<" ";//结果2 4 5 7 已经排序好了
}
rbegin()与rend()函数
返回反向迭代器
size()函数
返回元素个数
cout<<s.size()<<endl;//返回元素个数
empty()函数
返回容器是否为空,空则返回1,非空返回0
STL之multiset容器
与set容器类似,区别只在于multiset容器可以保存值相同的元素。
count(val)函数
返回val值出现的次数
STL之unordered_set容器
unordered_set容器底层为哈希表,查询插入的时间复杂度为O(1)
set1.insert(3); //插入元素,返回pair<unordered_set::iterator, bool>
set1.insert({1,2,3}); //使用initializer_list插入元素
set1.insert(set1.end(), 4);//指定插入位置,如果位置正确会减少插入时间,返回指向插入元素的迭代器
set1.insert(set2.begin(), set2.end());//使用范围迭代器插入
STL之map容器
Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的。
**时间复杂度O(log n) **
构造函数
map<key,value> m;
map<int,string> m;//默认构造一个Map容器
数据插入
//map数据插入 insert()
//1、插入pair ,如果key存在,不能更改
m.insert(pair<int,string>(1,"abcdefg"));
//2、直接插入, 如果key存在,不能更改
m.insert({2,"hijkl"});
//3、数组插入,如果key存在,覆盖其值
m[5]="aaaaaa";//5==key “aaaaa”== value
数据遍历
正向迭代器
map<int,string>::iterator it;
for(it=m.begin();it!=m.end();it++){//遍历
cout<<it->first<<" "<<it->second<<endl;//first 关键字, second 关键字的值
}
反向迭代器
map<int,string>::reverse_iterator rit;
for(rit=m.rbegin();rit!=m.rend();rit++){//反向遍历
cout<<rit->first<<" "<<rit->second<<endl;
}
数组方式
注意:int i=1; i<=m.size();
for(int i=1;i<=m.size();i++){//数组方式遍历
cout<<m[i]<<" ";
}
数据查找
find()函数
cout<<endl<<m.find(2)->second<<endl;//find(2)返回找到2位置的迭代器,若找不到则返回end();
在map中同样可以用lower_bound()和upper_bound()函数。
数据删除
iterator erase(iterator it);//通过一个条目对象删除
iterator erase(iterator first,iterator last)//删除一个范围
size_type erase(key);//通过关键字删除 ,删除返回1,否则返回0;
实际操作
#include<bits/stdc++.h>
using namespace std;
int main(){
map<int,string> m;//默认构造一个Map容器
//map数据插入 insert()
//1、插入pair ,如果key存在,不能更改
m.insert(pair<int,string>(1,"abcdefg"));
//2、直接插入, 如果key存在,不能更改
m.insert({2,"hijkl"});
//3、数组插入,如果key存在,覆盖其值
m[5]="aaaaaa";//5==key “aaaaa”== value
map<int,string>::iterator it;
for(it=m.begin();it!=m.end();it++){//遍历
cout<<it->first<<" "<<it->second<<endl;//first 关键字, second 关键字的值
}
cout<<m.size()<<endl;//查看map数据个数
map<int,string>::reverse_iterator rit;
for(rit=m.rbegin();rit!=m.rend();rit++){//反向遍历
cout<<rit->first<<" "<<rit->second<<endl;
}
for(int i=1;i<=m.size();i++){//数组方式遍历
cout<<m[i]<<" ";
}
cout<<endl<<m.find(2)->second<<endl;//find(2)返回找到2位置的迭代器,若找不到则返回end();
return 0;
}
STL之multimap容器
与map容器类似,区别只在于multimap容器可以保存键值相同的元素。
count()函数
可以知道有多少个元素的键和给定的键相同
int n=m.count(2);//返回键值为2
STL之unordered_map容器
时间复杂度O(1);
存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的
构造函数
unordered_map<int , char> um;//默认创建一个空的无序图
数据插入
insert()函数
pair<int ,char> p(2,'a');
um.insert(p);//复制插入
um.insert(make_pair<int,char>(5,'v'));//直接插入
um.insert(um.begin(),um.end());//范围插入
um.insert({6,'x'});//初始化数组插入
um[1]='b';//数组形式插入
数据查找
find();找到返回迭代器,没找到返回end()
cout<<(*um.find(2)).second<<endl; //==um.find(2)->second
数据删除
erase()函数
um.erase(um.begin());//通过迭代器
um.erase(2);//通过关键
字数据修改/调用
at(key)函数、[]调用
um[5]='w';//修改 {5,'v'}为{5,'w'}
cout<<um[5]<<endl;
cout<<um.at(6)<<endl;//调用
实际操作
#include<bits/stdc++.h>
using namespace std;
int main(){
unordered_map<int , char> um;//默认创建一个空的无序图
unordered_map<int,char> um1;
pair<int ,char> p(2,'a');
um.insert(p);//复制插入
um.insert(make_pair<int,char>(5,'v'));//直接插入
um.insert(um.begin(),um.end());//范围插入
um.insert({6,'x'});//初始化数组插入
um[1]='b';//数组形式插入
unordered_map<int,char>::iterator it;
for(it=um.begin();it!=um.end();it++){//遍历 无序的
cout<<it->first<<" "<<it->second<<endl;
}
cout<<(*um.find(2)).second<<endl; //==um.find(2)->second
um.erase(um.begin());//通过迭代器
um.erase(2);//通过关键字
for(it=um.begin();it!=um.end();it++){//遍历 无序的
cout<<it->first<<" "<<it->second<<endl;
}
um[5]='w';//修改 {5,'v'}为{5,'w'}
cout<<um[5]<<endl;
cout<<um.at(6)<<endl;//调用
return 0;
}