STL是C++提供的模板库,其中封装了很多容器(例如vector,string,set,map等等),我们不需要去实现他们的细节,直接调用函数来实现功能即可。例如我们之前学习过的栈,队列,链表等等都可以直接调用STL里面相应的容器即可。但我们也需要知道他们底层用的什么原理来实现的,这样做起题才会直接想到用什么容器。
Vector 意为"向量",这里是可变数组的意思,我们经常用到这个容器来代替数组,因为他是可变的,这里要注意,我们也要考虑到他的一个缺点就是,如果要扩容,则扩大为当前容量的两倍。所以我们知道数组的上限时,就用数组,不知道就用vector。
vector底层原理:数组拷贝。所以说,vector的查询快,删除(erase)和插入(insert)慢。
(1). 一维数组的定义
vector< typename> name; typename可以是int,double,char,node等。
(2).二维数组的定义
vector> v;//行和列都为可变的
vector< int > v[size];//列为可变的,而行是固定的
(1).通过下标直接访问
v[index] ( 0<=index(2).通过迭代器访问
c++里面有一个类似于指针的容器,叫迭代器,其定义为
vector< typename>::iterator it;
这样我们就得到了迭代器it,并且通过*it来访问vector里面的元素。
例如已经处理好的vector里面有1,2,3,4,5个元素,然后进行访问
这里说两个方式,普通遍历和迭代器遍历
- for(int i=0;i
- for(vector< int>::iterator it=v.begin();it!=v.end();it++)
printf("%d ",*it);
(1).push_back(x):在容器后面添加一个x元素,O(1);
(2).pop_back():删除容器末尾的元素,O(1);
(3).size():返回容器里面的个数 ,O(1);
(4).clear():清除容器里面的所有元素,O(N);
(5).insert(it,x):向容器的迭代器it处添加一个元素x,O(N);
(6).erase()有两种重载函数,代表删除元素,O(N):
erase(it):顾名思义就是删除迭代器it位置的元素;
erase(first,last):删除[first,last)内的所有元素,first和last都是迭代器。
(1). vector在元素个数不确定是用来存储数据能很好的节省空间。
(2). vector在我们后面学习图论的章节经常用来实现邻接表。
#include
#include
#include
using namespace std;
int main(){
vector<int> v;
for(int i=0;i<5;i++){
//1.从末尾压入元素
v.push_back(i);
printf("%d ",i);
}
puts("\n删除尾元素");
v.pop_back();
printf("元素个数:%d\n",v.size());
for(vector<int>::iterator it=v.begin();it!=v.end();it++){
printf("%d ",*it);
}
v.clear();
puts("");
for(int i=0;i<10;i++){
v.insert(v.begin()+i,i);
printf("%d ",i);
}
puts("\n删除v[4]这个元素");
v.erase(v.begin()+4);
for(vector<int>::iterator it=v.begin();it!=v.end();it++){
printf("%d ",*it);
}
puts("\n删除v[4],v[5]这两个元素");
v.erase(v.begin()+4,v.begin()+6);
for(int i=0;i<v.size();i++){
printf("%d ",v[i]);
}
return 0;
}
string是一个字符串容器,我们学c语言学过char字符数组,string比char操作起来更加方便,因为string包含了很多的函数。
string str; 在定义时可以初始化
直接访问即可,str[index] ( 0<=index
迭代器的访问和vector一样,在后面的代码会有演示到。
(1).operator+=:讲两个string直接拼接起来,这是使用了运算符重载。
(2).compare operator:两个string可以直接使用==,!=,<,<=,>,>=比较大小,比较规则是字典序。
(3).size()或者length():返回string的长度,O(1)
(4).insert()有两种重载函数,代表插入字符串,O(len)
insert(index,string):在index号位置插入字符串string
insert(it,it2,it3): it表示原串想插入的迭代器位置,it2和it3表示待插入字符串的首尾迭代器,串2[it2,it3)被插入到串1的it位置处。
(5).erase()有三种重载函数,代表删除字符串,O(len)
erase(it):代表删除it迭代器位置的字符
erase(first,last):代表删除迭代器在[first,last)这个区间的字符。
erase(pos,length):pos为只是位置,length 是删除字符个数。
(6).clear():用于清空string里的数据,O(1);
(7).substr(pos,len):截取从pos位置开始,len长的子串,O(len)
(8).find()有两种重载函数,代表查找字符串位置,O(n*m):
find(str2):当str2是str的子串时,返回在str中第一次出现的位置,如果不是(查找失败),则会返回-1或者unsigned_int的最大值。
find(str2,pos),从str的pos位置开始匹配,返回值和上面相同。
(9).replace()有两种重载函数,代表替换字符串,O(len)
replace(pos,len,str2),str从pos位置开始,长度为len的子串替换为str2
replace(it1,it2,str2),将str迭代器在[it1,it2)替换为str2.
#include
#include
using namespace std;
int main(){
//字符串定义,输出,比较
string str1="1111",str2="222";
str2+="2";
string temp=str1+str2;
cout<<"temp: "<<temp<<endl;
cout<<"str1: "<<str1<<"\tstr2: "<<str2<<endl;
if(str1>str2) puts("str1的字典序大于str2的字典序");
else if(str1==str2) puts("str1的字典序等于str2的字典序");
else puts("str1的字典序小于str2的字典序");
printf("temp的字符串长度%d:\n",temp.length());
//字符串插入
temp.insert(4,str2);
cout<<"将字符串从4位置处,插入一个str2,temp: "<<temp<<endl;
temp.insert(temp.begin(),str1.begin(),str1.end());
cout<<"将字符串从0位置开始,插入一个字符串str1,temp: "<<temp<<endl;
//字符串删除
temp.erase(temp.begin());
cout<<"删除temp的第一个元素,temp: "<<temp<<endl;
temp.erase(temp.begin(),temp.begin()+2);
cout<<"删除[0,2)区间内的字符,temp: "<<temp<<endl;
temp.erase(0,4);
cout<<"删除从0开始,长度为4的字符串,temp: "<<temp<<endl;
//字符串清除,字符串输入,字符串截取
temp.clear();
puts("输入一个字符串");
cin>>temp;
temp=temp.substr(0,4);
cout<<"截取[0,4)的字符串,temp: "<<temp<<endl;
//字符串查找和取代
temp=str1+str2+str1+str2;//str1="abcd",str2="efgh"
cout<<"temp: "<<temp<<endl;
cout<<"查找字符串str1在temp字符串中的第一次位置,记过为:"<<temp.find(str1)<<endl;
cout<<"查找字符串str2从3开始的是存在于temp的位置,结果为:"<<temp.find(str2,3)<<endl;
cout<<"将字符串temp的3位置,取代4个长度的str1,结果为:"<<temp.replace(3,4,str1)<<endl;
cout<<"将字符串temp的1,4区间的字符,用str2代替,结果为:"<<temp.replace(temp.begin()+1,temp.begin()+4,str2)<<endl;
return 0;
}