如果容器是你对STL的唯一印象,说明你利器(STL)在手而未能善用。容器可以分为序列容器(Sequential Containers)和关联容器(Associative Containers)。下面我们将从创建、插入、删除、查看五个方面演示如何使用容器。
序列容器
序列容器中常见的vector、list、deque、priority-queue等。
Ø vector
vector和数组很相似,但大小是动态可变的,不需要自己控制。下面我们将以存储int型元素的vector为例,仔细讲解如何使用vector。
---创建vector---
vector<int> iv; //方式1,构建一个空的容器对象
vector<int> iv(2, 9); //方式2,构建一个包含2个值为9的容器对象
int a[4] = { 1, 2, 3, 4 };
vector<int> iv(a, a+3); //方式3,利用数组指针构建容器对象(也可以利用其它容器迭代器)
vector<int> iv2(iv); //方式4,利用其它vector对象构建容器对象
vector<int> iv3 = iv; //方式4的另一种写法
---插入操作---
iv.push_back(2); //方式1,在队尾插入一个元素
iv.insert(iv.begin(),5); //方式2,在指定位置插入1个元素
iv.insert(iv.begin()+1,3, 9); //方式3,在指定位置插入多个元素
iv.emplace(iv.begin(),1); //方式4,在指定位置插入1个元素(效率更高,不创建临时变量)
iv.emplace_back(1); //方式5,在队尾插入1个元素(效率更高,不创建临时变量)
---删除操作---
iv.erase(iv.begin()); //方式1,删除指定位置的1个元素
iv.erase(iv.begin(),iv.begin() + 2); //方式2,删除指定位置的多个元素
iv.pop_back(); //方式3,删除队尾元素
iv.clear(); //方式4,清空所有元素
---查看操作---
iv[1]; //方式1,查看指定位置的元素(注意防止越界访问)
iv.at(1); //方式2,查看指定位置的元素(从0计数,注意防止越界访问)
iv.front(); //方式3,查看头部的元素
iv.back(); //方式4,查看尾部的元素
*iv.begin(); //方式5,使用迭代器查看元素
---遍历操作---
//从前往后遍历
for(vector<int>::iteratoriter = iv.begin(); iter++; iter!= iv.end()){
//dosomething
}
//从后往前遍历
for(vector<int>::iteratoriter = iv.rbegin(); iter++; iter!= iv.rend()){
//dosomething
}
//利用for_each进行遍历
for_each(iter.begin(),iter.end(), dosomething);
---其它操作---
il.empty(); //判断容器是否为空
iv.size(); //返回容器的size(大小)
iv.capacity(); //返回容器的capacity(容量)
iv.reserve(10); //调整容器的capacity为10,如果原值大于10,则不处理
iv.resize(10); //调整容器的size为10,如果原值大于10,则删除元素
iv.data(); //返回第一个元素的指针
iv.assign(5,2); //清空所有元素,并插入5个值为2的元素
iv.assign(iter1,iter2);//清空所有元素,并根据迭代器(或数组指针)进行赋值
iv.swap(iv2); //两个容器互相交换内容
iv. shrink_to_fi();//请求容器减小容量使其足够用来存放所有有效元素
---注意事项---
当vector的空间动态调整时,并不是在原空间之后增加新的空间,而是以原空间大小的二倍申请新的空间,然后将原内容拷贝过来,然后才在新空间构造新元素,并且释放原空间。因此,对vector的操作如果引起空间重新配置,则指向原vector元素的所有指针和迭代器都将失效!如果再访问这些地址,将发生不可预测的错误。千万小心!
同时,当进行插入、删除操作时,操作位置之后的迭代器全部失效!