一、vector
vector是“长度根据需要而自动改变的数组”。在算法中,有时会碰到使用普通数组就会超内存的情况,这种情况下可以使用vector数组。另外,vector数组还可以用来以邻接表的方式存储图,这对于无法使用邻接矩阵、又害怕使用指针实现邻接表的题目是非常友好的。
使用vector,需要添加头文件#include< vector >。除此之外,还要添上一句“using namespace std”。
1、vector的定义:
vector<typename> name;
typename为基本数据类型:
vector<int> name;
vector<double> name;
vector<char> name;
vector<node> name;//node是结构体类型
vector也可以为STL标准容器,但是这种情况下,定义时要在>>中间加上空格,因为某些编译器会将其认为是移位操作,导致编译错误。如下:
vector<vector<int> > name;
上面这种方法可以联想到二维数组,可以将这个二维的vector数组当做是两个维都可以边长的二维数组理解。
定义vector数组:
vector<typename> ArrayName[arraySize];
上面这种定义的方式将一维长度固定为arraySize
2、vector容器内元素的访问:
通过下标访问:同普通数组,下标从0~vi.size()-1
通过迭代器访问:迭代器可以理解为一种类似指针的东西
vector<typename>::iterator it;
这样得到了迭代器it,可以通过*it来访问里面的元素
#include<stdio.h>
#include<vector>
using namespace std;
int main(){
vector<int> vi;
for(int i = 0 ; i < 5 ; i++)
vi.push_back(i);//在vi末尾依次添加元素i
vector<int>::iterator it = vi.begin();//it指向vi的首地址
for(int i = 0 ; i < 5 ; i++)
printf("%d ",*(it+i));
return 0;
}
另外还有一种访问方式:
//迭代器能够实现自增操作
for(vector<int>::iterator it = vi.begin();it!=vi.end();it++)
printf("%d ",*it);
3、push_back()函数:
push_back(x)是指在vector后面添加一个元素x,时间复杂度为O(1)
4、pop_back()函数
删除vector末尾的元素,时间复杂度为O(1)
#include<stdio.h>
#include<vector>
using namespace std;
int main(){
vector<int> vi;
for(int i = 0 ; i < 5 ; i++)
vi.push_back(i);//在vi末尾依次添加元素i
vi.pop_back();
//迭代器能够实现自增操作
for(vector<int>::iterator it = vi.begin();it!=vi.end();it++)
printf("%d ",*it);
return 0;
}
5、size()
获取vector中元素的个数,时间复杂度为O(1)
6、clear()
用来清空vector中所有的元素
7、insert()
insert(it,x):用来想vector的任意迭代器it处插入一个元素x,时间复杂度为O(N)
#include<stdio.h>
#include<vector>
using namespace std;
int main(){
vector<int> vi;
for(int i = 1 ; i <= 5 ; i++)
vi.push_back(i);//在vi末尾依次添加元素i
vi.insert(vi.begin()+2,-1);//将-1插入到vi[2]的位置
for(int i = 0 ; i < vi.size() ; i++)
printf("%d ",vi[i]);
return 0;
}
8、erase()
删除单个元素erase(it):删除迭代器为it处的元素
#include<stdio.h>
#include<vector>
using namespace std;
int main(){
vector<int> vi;
for(int i = 1 ; i <= 5 ; i++)
vi.push_back(i);//在vi末尾依次添加元素i
vi.erase(vi.begin()+2);//将-删除vi[2]
for(int i = 0 ; i < vi.size() ; i++)
printf("%d ",vi[i]);
return 0;
}
erase(first,last):删除[first,last)区间内的元素
#include<stdio.h>
#include<vector>
using namespace std;
int main(){
vector<int> vi;
for(int i = 1 ; i <= 5 ; i++)
vi.push_back(i);//在vi末尾依次添加元素i
vi.erase(vi.begin()+2,vi.begin()+4);//将-删除vi[2]、vi[3]
for(int i = 0 ; i < vi.size() ; i++)
printf("%d ",vi[i]);
return 0;
}
常见用途:
- 在元素不确定的场合能够节省空间
- 由于有些场合输出元素个数不确定,为了更方便地处理最后一个满足条件地元素后面不输出额外的空格,可以先用vector记录所有需要输出的元素然后一次性输出
- 用邻接表存储图
二、set
set是一个内部自动有序切不含重复元素的集合。使用时需要添加#include< set >以及using namespace std;
1、set的定义:
set<typename> name;
具体定义方式同vector
2、set内元素的访问:
set只能通过迭代器去访问,并且除了vector和String之外的STL容器都不支持*(it+i)的访问方式,因此只能按照以下方式枚举:
#include<stdio.h>
#include<set>
using namespace std;
int main(){
set<int> st;
st.insert(3);//将3插入st中
st.insert(5);
st.insert(2);
st.insert(3);
//注意:不支持it<st.end()写法
for(set<int>::iterator it = st.begin();it!=st.end();it++)
printf("%d ",*it);
return 0;
}
可以发现set内的元素自动递增排序并且去除了重复元素
3、insert()
insert(x)可以将x插入到Set容器中,并自动递增排序和去重
4、find()
find(value)返回set中对应值为value的迭代器
#include<stdio.h>
#include<set>
using namespace std;
int main(){
set<int> st;
for(int i = 1 ; i <=3 ; i++)
st.insert(i);
set<int>::iterator it = st.find(2);
printf("%d",*it);
return 0;
}
5、erase()
删除单个元素:st.erase(it),it为所需要删除元素的迭代器,可以结合find()函数使用;st.erase(value),value为所需要删除元素的值
删除一个区间内的元素:st.erase(first,last),删除区间[first,last)内的元素
#include<stdio.h>
#include<set>
using namespace std;
int main(){
set<int> st;
st.insert(20);
st.insert(10);
st.insert(40);
st.insert(30);
set<int>::iterator it = st.find(30);
st.erase(it,st.end());//st.end()指向末尾元素的下一个位置,这里即删除30、40
for(it = st.begin();it!=st.end();it++)
printf("%d ",*it);
return 0;
}
6、size()
用来获取set内元素的个数
7、clear()
用来清空set内所有的元素
三、string
在C语言中,一般使用字符数组char str[]来存放字符串,C++引入了string类型,对字符串的常用功能进行了封装。使用string需要添加#include< string >以及using namespace std;(string.h和string是不一样的头文件)
1、string的定义:
string str;
string str1 = "abcd";
2、string中内容的访问:
(1)通过下标访问:
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int main(){
string str;
cin>>str;
for(int i = 0 ; i < str.length() ; i++)
printf("%c",str[i]);
return 0;
}
(2)通过迭代器访问:
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int main(){
string str;
cin>>str;
for(string::iterator it = str.begin();it!=str.end();it++)
printf("%c ",*it);
return 0;
}
3、operator+=
可以将两个string直接拼接起来
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int main(){
string str1,str2,str3;
cin>>str1;
cin>>str2;
str3 = str1+str2;
cout<<str3;
return 0;
}
4、compare operator
两个string类型可以用==、!=、<、<=、>、>=来比较大小,比较的规则是字典序
5、length()/size()
length()返回string的长度,即存放的字符数
6、insert()
insert(pos,string),在pos号位置插入string
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int main(){
string str1,str2;
cin>>str1;
cin>>str2;
str1.insert(2,str2);
cout<<str1;
return 0;
}
insert(it,it2,it3):it为原字符串的欲插入的位置,it2,it3为待插入字符串的首位迭代器,表示串[it2,it3)被插入在it的位置上
7、erase()
删除单个元素:str.erase(it) it为需要删除的元素的迭代器
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int main(){
string str = "abcdefg";
str.erase(str.begin()+4);
cout<<str;
return 0;
}
删除一个区间内的元素:str.erase(first,last),删除区间[first,last)内的元素
删除一个区间内的元素:str.erase(pos,length),pos为需要开始删除元素的起始位置,length为删除的字符个数
8、clear()
清空string中的数据
9、substr()
substr(pos,len):从pos位开始,长度为len的字串
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int main(){
string str = "Thank you for your smile.";
cout<<str.substr(0,5)<<endl;//Thank
cout<<str.substr(14,4)<<endl;//your
cout<<str.substr(19,5)<<endl;//smile
return 0;
}
10、string::npos
string::npos是一个常数,其值本身为-1,但是由于是unsigned int类型,因此也可以认为是unsigned int的最大值。它用以作为find()函数失配的返回值
11、find()
str.find(str2):当str2是str的字串时,返回其在str中第一次出现的位置,如果str2不是str的字串就返回string::npos
str.find(str2,pos):从str的pos位开始匹配str2,返回值同上
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int main(){
string str = "Thank you for your smile.";
string str2 = "you";
if(str.find(str2)!=string::npos){
cout<<str.find(str2)<<endl;
}
return 0;
}
12、replace()
str.replace(pos,len,str2):把str从pos位开始、长度位len的字串替换位str2
str.replace(it1,it2,str2):把str的迭代器[it1,it2)范围内的字串替换位str2
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int main(){
string str = "Maybe you will turn around.";
string str2 = "will not";
string str3 = "surely";
cout<<str.replace(10,4,str2)<<endl;
cout<<str.replace(str.begin(),str.begin()+5,str3);
return 0;
}
四、map
map翻译为映射。map可以将任何基本类型(包括STL容器)映射为任何基本类型(包括STL容器)。使用map,需要添加#include< map >头文件以及using namespace std;
1、map定义
map<typename1,typename2> mp; //第一个是键的类型,第二个是值的类型,键是唯一的
如果是字符串到整型的映射,必须使用string而不是char数组
map<string,int> mp;
map中元素的访问:
(1)通过键访问(键是唯一的):
#include<map>
#include<stdio.h>
using namespace std;
int main(){
map<char,int> mp;
mp['c'] = 20;
mp['c'] = 30;
printf("%d\n",mp['c']);//30
return 0;
}
(2)通过迭代器进行访问
map<typename1,typename2>::iterator it;
通过it->first访问键,通过it->second访问值
#include<map>
#include<stdio.h>
using namespace std;
int main(){
map<char,int> mp;
mp['m'] = 20;
mp['r'] = 30;
for(map<char,int>::iterator it = mp.begin();it!=mp.end();it++){
printf("%c %d\n",it->first,it->second);
}
return 0;
}
map的键会从小到大自动排序
3、find():
find(key)返回键为key的映射的迭代器
#include<map>
#include<stdio.h>
using namespace std;
int main(){
map<char,int> mp;
mp['m'] = 20;
mp['r'] = 30;
map<char,int>::iterator it = mp.find('m');
printf("%c %d\n",it->first,it->second);//m 20
return 0;
}
4、erase()
删除单个元素:mp.erase(it) it为要删除de 元素的迭代器
删除单个元素:mp.erase(key):key为欲删除的映射的键
删除一个区间内的元素:mp.erase(first,last),first和last均为迭代器,删除元素的区间为[first,last)
5、size()
获取map中映射的对数
6、clear()
清空map中的所有元素
常见用途:
- 需要建立字符或者字符串与整数之间的映射的题目
- 判断大整数或者其他类型数据是否存在的题目,可以将map当做bool数组使用
注意:map的键和值是一一对应的,如果想要一个键对应多个值,需要使用multimap