1.顺序容器的类型
顺序容器有:
vector 支持快速随机访问
list 支持快速插入、删除
deque 双端队列
为了适应基础的容器类型,又定义了三种容器的适配器
stack 堆栈
queue 队列
priority_queue 有优先级管理的队列
2.定义
#include<vector>
#include<list>
#include<deque>
vector<string> spev;
list<char> ppre;
deque<int> prio;
3.初始化副本
注:将一个容器复制给另一个容器时,容器类型和元素类型都必须相同。
例如:
vector<int> ivec;
vector<int> ivec2(ivec); //right
list<int> ilist(ivec); //error
vector<double> dvec(ivec); //error
4.初始化一段元素的副本
使用迭代器来复制其他容器的元素
list<string> slist(svec.begin(),svec.end());
vector<string>::iterator mid=svec.begin()+svec.size()/2;
deque<string> front(svec.begin(),mid);
deque<string> front(mid,svec.end());
解释复制容器对象的构造函数和使用两个迭代器的构造函数之间的差别
前者必须容器类型和元素类型都必须相同;后者只需元素类型相同,而且可以复制子序列,并不一定是全部,所以显得更加灵活。
5.容器的容器:相当于是副本存储
list< deque<int> >ilist;
6.常用的迭代器运算
*iter,iter->mem,
( *iter ).mem, ++iter, iter++, –iter, iter–, iter1==iter2, iter1!=iter2;
但是vector和deque提供额外的迭代器运算
iter+n, iter-n
注:关系操作符只适用于vector和deque操作符。
#include"stdafx.h"
#include<iostream>
#include<vector>
using namespace std;
typedef vector<int>::iterator iter;
bool find(iter first,iter last,int n)
{
if(first>last)
cout<<"iterator error"<<endl;
for(iter i=first;i!=last;++i)
{
if(*i==n)
return true;
}
return false;
}
int main()
{
//用数组去初始化
int ai[]={1,2,3,4,5,6,7,8,9};
vector<int> spev(ai,ai+8);
int x;
cout<<"please input number:\n";
cin>>x;
bool find3=false;
find3=find(spev.begin(),spev.end(),x);
if(find3)
cout<<"got it!"<<endl;
else
cout<<"error"<<endl;
system("pause");
return 0;
}
7.顺序容器的操作
在顺序容器中添加元素的操作:
c.push_back(t)
c.push_front(t)
c.insert(p,t)
c.insert(p,n,t)
c.insert(p,b,e) //在迭代器p后添加迭代器b和迭代器e之间的元素
8.容器大小的操作
c.size()
c.max_size()
c.empty()
c.resize(n)
c.resize(n,t)
9.访问元素
c.back() //返回容器c的最后一个元素的引用
c.front() //返回容器c的第一个元素的引用
c[n] //返回下标为n的元素的引用
c.at(n) //返回下标为n的元素的引用
10.删除元素
c.erase(p) //迭代器p所指的元素
c.erase(b,e) //删除迭代器b和e所标记的范围内所有的元素
c.clear() //删除所有元素
c.pop_back() //最后一个元素
c.pop_front() //第一个元素
11.赋值与swap操作
c1.swap(c2); //c1和c2必须容器类型相同,元素类型也相同
c.assign(b,e); //将迭代器b和e的元素复制到c中
注:在不同类型的容器内,元素类型不相同但是相互之间兼容,则其赋值运算使用assign()为好。例如:
#include"stdafx.h"
#include<iostream>
#include<vector>
#include<string>
#include<list>
using namespace std;
int main()
{
char * ha[]={"hello","world","htp"};
list<char *> iList;
iList.assign(ha,ha+3);
for(list<char*>::iterator its=iList.begin();its!=iList.end();++its)
cout<<*its<<"\t";
cout<<endl;
vector<string>iVec;
iVec.assign(iList.begin(),iList.end());
for(vector<string>::iterator it=iVec.begin();it!=iVec.end();++it)
{
cout<<*it<<endl;
}
system("pause");
return 0;
}
一般而言,list容器优于vector容器。因为list容器的元素并非以顺序结构存储的。
12.容器适配器
标准库提供了三种顺序容器适配器:queue, priority_queue, stack。适配器是标准库中通用的概念,包括容器适配器,迭代适配器和函数适配器。
#include<stack>
#include<queue>
初始化:stackstk;
栈适配器的基本操作:
s.empty();
s.size();
s.pop();
s.top();
s.push()
队列和优先级队列的操作:
q.empty();
q.size();
q.pop();
q.front();
q.back();
q.top();
q.push(item);
习题9.43
使用 stack对象处理带圆括号的表达式。遇到左 圆括号时, 将其标记下来。然后遇到右圆括号时, 弹出 stack对象中这两边括 号之间的相关元素(包括左圆括号)。接着在stack对象中压入一个值,用以表明这个用一对圆括号括起来的表达式已经被替换。
#include "stdafx.h"
#include <iostream>
#include <string>
#include <stack>
#include <deque>
using namespace std;
int main()
{
stack<char> sExp;
string strExp;
cout << " Input a expression: ";
cin >> strExp;
// deal the sExp
string::iterator it = strExp.begin();
while ( it != strExp.end() )
{
if ( *it != ')' )
sExp.push( *it );
else
{
while ( ( sExp.top() != '(' ) && !sExp.empty() )
{
sExp.pop();
}
}
if ( sExp.empty() )
cout << " It's not matched. " << endl;
else
{
sExp.pop();
sExp.push('@');
}
++it;
}
// show out the elements of the stack
cout << "\nThe elements of the stack are:" << endl;
while ( ! sExp.empty() )
{
cout << sExp.top() << endl;
sExp.pop();
}
system("pause");
return 0;
}