常用的STL容器
STL容器很多,每一个容器就是一个类模板
一、容器种类
①顺序容器
②适配器容器
③关联容器
可参考
算法设计与分析——常用的STL容器(二)
二、顺序容器
(1)vector(向量容器)
①相当于数组,存储具有相同数据类型的一组元素。如果初始分配的空间不够,当超过空间大小时会重新分配更大的空间(通常按照两倍大小扩展),此时需要进行大量的元素复制,从而增加了性能开销。
②定义vector容器的几种方法如下:
vector<int> v1; //定义元素蔚int的向量v1
vector<int> v2(10);//指定向量v2的初始大小蔚10个int元素
vector<double> v3(10,1.23);//指定v3的10个初始元素的初始值为1.23
vector<int> v4(a,a+5);//用数组a[0...4]共5个元素初始化v4
③vector提供了一系列的成员函数,vector的主要成员函数如下:
●empty():判断当前向量容器是否为空
●size():返回当前向量容器中的实际元素个数
●[ ]:返回指定下标的元素
●reserve(n):为当前向量容器预分配n个元素的存储空间
●capacity():返回当前向量容器在重新进行内存分配以前所能容纳的元素个数
●resize(n):调整当前向量容器的大小,使其能容纳n个元素
●push_back():在当前容器尾部添加一个元素
●insert(pos,elem):在pos位置插入元素elem,即讲元素elem插入到迭代器pos指定的元素之前
●front():获取当前向量容器的第一个元素
●back():获取当前向量容器的最后一个元素
●erase():删除对当前向量容器中某个迭代器或者迭代器区间指定的元素
●clear():删除当前向量容器中的所有元素
●begin():该函数的两个版本返回iterator或者const_iterator,引用容器的第一个元素
●end():该函数的两个版本返回iterator或者const_iterator,引用容器的最后一个元素后面的一个位置
●rbegin():该函数的两个版本返回reverse_iterator或者const_reverse_iterator,引用容器的最后一个元素
●rend():该函数的两个版本返回reverse_iterator或者const_reverse_iterator,引用容器的第一个元素前面的一个位置
④例如,如下程序说明vector容器的应用
#include<vector>
using namespace std;
void main(){
vector<int> myv;
vector<int>::iterator it;
myv.push_back(1);
it=myv.begin();
myv.insert(it,2);
myv.push_back(3);
myv.push_back(4);
it=myv.end();
it--;
myv.earse(it);
for(it=myv.begin();it!=myv.end();++it)
printf("%d",*it);
printf("\n");
}
上述程序输出为:2 1 3
(2)string(字符串容器)
①string是一个保存字符序列的容器,它的所有元素为字符类型,相当于>vector<char
,因此除了有字符串的一些常用操作以外,还包含了所有序列容器的操作,字符串的常用操作包括增加、删除、修改、查找、比较、连接、输入、输出等。string重载了许多运算符包括+,+=,<,=,[ ],<<和>>等。正是有了这些运算符,使用string实现字符串的操作变得非常方便和简洁。
②创建string容器的几种方式如下:
●string():建立一个空的字符串
●string(const string& str):用字符串str建立当前字符串。
●string(const string& str,size_type str_idx):用字符串str起始于str_idx的字符建立当前字符串。
●string(const string& str,size_type str_idx,size_type str_num):用字符串str起始于str_idx的str_num个字符建立当前字符串。
●string(const char* chars,size_type chars_len):用字符串cstr开头的chars_len个字符建立当前字符串
●string(size_type num,char c):用num个字符c建立当前字符串
例如:
char cstr[]="China!Great Wall";
string s1(cstr);//s1:China!Great Wall
string s2(s1);//s2:China!Great Wall
string s3(cstr,7,11);//s3:Great Wall
string s4(cstr,6);//s4:China!
string s5(5,'A');//s5:AAAAA
③用于实现各种常用字符串操作功能的成员函数:
▶empty():判断当前字符串是否为空串
▶size():返回当前字符串的实际字符个数
▶length():返回当前字符串的实际字符个数
▶[idx]:返回当前字符串位于idx位置的字符,idx从0开始
▶at(idx):返回当前字符串位于idx位置的字符
▶compare(const string& str):返回当前字符串与字符串str的比较结果,在比较时,若两者相等,返回0;若前者小于后者返回-1,否则返回1
▶append(cstr):在当前字符串的末尾添加一个字符串str
▶insert(size_type idx,const string& str):在当前字符串的idx处插入一个字符串str
▶find(string& s,size_type pos):从当前字符串的pos位置开始查找字符串s的第一个位置,找到后返回其位置,否则返回-1
▶replace(size_type idx,size_type len,const string& str):将当前字符串中起始于idx的len个字符用一个str字符串替换
▶replace(iterator beg,iterator end,const string& str):将当前字符串中由迭代器beg和end所指区间的所有字符用一个字符串str替换
▶substr(size_type idx):返回当前字符串起始于idx的子串
▶substr(size_type idx,size_type len):返回当前字符串起始于idx的长度为len的子串
▶clear()/erase():删除当前字符串中的所有字符
▶erase(size_type idx):删除当前字符串从idx开始的所有字符
▶erase(size_type idx):删除当前字符串从idx开始的len个字符
例如以下程序:
#include<iostream>
#include<string>
using namespace std;
void main(){
string s1=" ",s2,s3="Bye";
s1.append("Good morning");
s2=s1;
int i=s2.fid("morning");
s2.replace(i,s2.length()-i,s3);
cout<<"s1:"<<s1<<endl;
cout<<"s2:"<<s2<<endl;
执行结果:
s1:Good morning
s2:Good Bye
(3)deque(双端队列容器)
①双端队列类模板,由若干个块构成,每个块中元素的地址是连续的,块之间的地址是不连续的。用户可以从前面或者后面快速地插入与删除元素,并且可以快速地随机访问元素,但在中间位置插入和删除元素速度较慢。
②deque容器不像vector那样把所有元素保存在一个连续的内存块,而是采用多个连续的存储块存放数据元素,所以空间的重新分配要比vector快,因为重新分配空间后原有的元素不需要复制。
③定义deque双端队列容器的几种方式如下
deque<int> dq1;//定义元素为int的双端队列dq1
deque<int>dq2(10);//指定dq2的初始大小为10个int元素
deque<double>dq3(10,1.23);//指定dq3的10个初始元素的初值为1.23
deque<int>dq4(dq2.begin(),dq2.end());//用dq2的所有元素初始化为dq4
④deque的主要成员函数如下:
empty():判断双端队列容器是否为空队
size():返回双端队列容器中的元素个数
front():取队头元素
back():取队尾元素
push_front(elem):在队头插入元素elem
push_back(elem):在队尾插入元素elem
pop_front():删除队头一个元素。
pop_back():删除队尾一个元素
erase():从双端队列容器中删除一个或者几个元素。
clear():删除双端队列中全部元素
begin():该函数的两个版本返回iterator或者const_iterator,引用容器的第一个元素。
end():该函数的两个版本返回iterator或者const_iterator,引用容器的最后一个元素后面的一个位置。
rbegin():该函数的两个版本返回reverse_iterator或者const_reverse_iterator,引用容器的最后一个元素
rend():该函数的两个版本返回reverse_iterator或者const_reverse_iterator,引用容器的第一个元素前面的一个位置
例如以下程序:
#include<deque>
using namespace std;
void disp(deque<int> &dp){
deque<int>::iterator iter;
for(iter=dq.begin();iter!=dq.end();iter++)
printf("%d",*iter);
printf("\n");
}
void main(){
deque<int> dq;
dq.push_front(1);
dq.push_back(2);
dq.push_front(3);
dq.push_back(4);
disp(dq);
sq.pop_front();
dq.pop_back();
disp(dq);
}
执行结果:
3 1 2 4
1 2
(4)list(链表容器)
①它是一个双链表类模板,它可以从任何地方快速插入与删除,它的每个结点之间通过指针连接,不能随机访问元素,为了访问表容器中特定的元素,必须从表头开始,随着指针从一个元素到下一个元素,直到找到要找的元素。list容器插入元素比vector快,对每个元素单独分配空间,所以不存在空间不够,所以不存在空间不够需要重新分配的情况。
②定义方式如下:
list<int> l1; //定义元素蔚int的链表l1
list<int> l2(10);//指定链表l2的初始大小蔚10个int元素
list<double> l3(10,1.23);//指定l3的10个初始元素的初始值为1.23
list<int> l4(a,a+5);//用数组a[0...4]共5个元素初始化l4
③list的主要成员函数:
●empty():判断当前链表是否为空`
●size():返回当前链表中的实际元素个数`
●push_back():在链表尾部插入元素
●reverse():反转链表
●pop_back():删除链表容器的最后一个元素
●remove():删除链表容器中所有指定值的元素
●remove_if(cmp):删除链表容器中满足条件的元素
●erase():从链表容器中删除一个或者几个元素。
●unique():删除链表容器中相邻的重复元素。
●clear():删除链表容器中所有元素
●insert(pos,elem):在pos位置插入元素elem
●insert(pos,n,elem):在pos位置插入n个元素elem
●insert(pos,pos1,pos2):在迭代器pos处插入[pos1,pos2)的元素
●reverse():反转链表
●sort():对链表容器中的元素排序
●begin():该函数的两个版本返回iterator或者const_iterator,引用容器的第一个元素。
●end():该函数的两个版本返回iterator或者const_iterator,引用容器的最后一个元素后面的一个位置。
●rbegin():该函数的两个版本返回reverse_iterator或者const_reverse_iterator,引用容器的最后一个元素
●rend():该函数的两个版本返回reverse_iterator或者const_reverse_iterator,引用容器的第一个元素前面的一个位置
④例如以下程序:
#include<list>
using namespace std;
void disp(list<int> &list) //输出list的所有元素
{
list<int>::iterator it;
for(it=list.begin();it!=list.end();it++)
printf("%d ",*it);
printf("\n");
}
int main(){
list<int>lst;
list<int>::iterator it,start,end;
lst.push_back(5);
lst.push_back(2);
lst.push_back(4);
lst.push_back(1);
lst.push_back(3);
printf("初始lst: ");
disp(lst);
it=lst.begin();
start=++lst.begin();
end=--lst.end();
lst.insert(it,start,end);
printf("插入后lst:");
printf("\n");
return 0;
}
执行结果:
初始lst:5 2 4 1 3
插入后lst:2 4 1 5 2 4 1 3
ps:此处值得特别注意的是insert(pos,pos1,pos2):在迭代器pos处插入[pos1,pos2)的元素