STL学习网址:
C语言中文网:http://c.biancheng.net/stl/vector是将元素放到动态数组中加以管理的容器。vector容器可以随机存取元素,也就是说支持[]运算符和at方式存取。
vector在尾部添加或者移除元素非常快,在中间操作非常耗时,因为它需要移动元素vector的基本用法
既然vector是容器,那么就可以向这个容器添加删除元素。
基本用法:
front()返回头部元素的引用,可以当左值back()返回尾部元素的引用,可以当左值push_back()添加元素,只能尾部添加pop_back()移除元素,只能在尾部移除初始化
第一种:用数组来初始化
int a[10] = {0}; vector<int> my_list1(a, a+10);第二种:直接初始化
vector<int> my_list1(10);//定义一个vector容器 vector<int> v1; //插入元素(尾部插入) v1.push_back(1); v1.push_back(2); v1.push_back(3); //迭代器遍历打印 for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl; //修改头部元素的值(front()返回是引用,可以当左值) v1.front() = 44; //输出头部元素 cout<<"头部元素:"<< v1.front() << endl; //修改尾部的值(back()返回是引用,可以当左值) v1.back() = 99; //输出尾部元素 cout << "尾部元素" << v1.back() <<endl; //删除元素(从尾部删除) v1.pop_back(); //迭代器遍历打印 for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl;
vector的遍历
vector的遍历有多种方式,可以根据[]或者迭代器遍历。
需要主要的是:
[]方式,如果越界或出现其他错误,不会抛出异常,可能会崩溃,可能数据随机出现at方式,如果越界或出现其他错误,会抛出异常,需要捕获异常并处理迭代器提供了逆向遍历,可以通过迭代器来实现逆向遍历,当然上面两种方式也可以 int main(int argc, const char * argv[]) { //创建vector vector<int> v1; //插入元素 for (int i = 0; i < 10; i++) { v1.push_back(i); } //遍历-[]取值 for (int i = 0; i < v1.size(); i++) { cout << v1[i] << " "; } cout << endl; //遍历-at取值 for (int i = 0; i < v1.size(); i++) { cout << v1.at(i) << " "; } cout << endl; //遍历-迭代器遍历 for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl; //遍历-迭代器逆向遍历 for (vector<int>::reverse_iterator it = v1.rbegin(); it != v1.rend(); it++) { cout << *it << " "; } cout << endl; //测试越界 cout << "[]越界:" << v1[20] << endl; //不会抛出异常,可能会崩溃,可能会乱码 cout << "at越界:" << v1.at(20) << endl; //会抛出异常,需要捕获异常 return 0; }vector的push_back强化
push_back是在当前vector的内存末尾拷贝元素进入容器。注意这个地方可能产生浅拷贝,所以容器中的对象要支持拷贝操作。另外,如果vector初始化了个数,而不初始化具体的值,push_back也只会在最后面追加。
//初始化10个元素的容器 vector<int> v(10); //打印容器大小 cout << v.size() << endl; //push_back添加元素 v.push_back(100); //打印容器大小 cout << v.size() << endl; //遍历后的结果是 0 0 0 0 0 0 0 0 0 0 100 for (vector<int>::iterator it = v.begin(); it != v.end(); it++) { cout << *it << " "; } cout << endl;vector的元素删除
vector的删除,是根据位置进行删除,如果想要删除某个元素,需要找到当前元素的迭代器位置,再进行删除。
iterator erase(iterator it); //删除向量中某一个元素 iterator erase(iterator first, iterator last) //删除向量中[first,last)中元素 void pop_back(); //删除向量中最后一个元素 void clear(); //删除向量中所有元素erase(iterator)函数,删除后会返回当前迭代器的下一个位置。
//1 创建容器并初始化 vector<int> v1(10); for (int i = 0; i < v1.size(); i++) { v1[i] = i; } //2 区间删除 //--2.1 删除前3个元素 v1.erase(v1.begin(), v1.begin() + 3); //--2.2 删除指定位置的元素 v1.erase(v1.begin() +3); //3 根据元素的值进行删除,删除值为2的元素 v1.push_back(2); v1.push_back(2); vector<int>::iterator it = v1.begin(); while (it != v1.end()) { if (*it == 2) { it = v1.erase(it); //删除后,迭代器指针会执行下一个位置并返回。 }else{ it++; } } //4 遍历打印 for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl;vector的插入元素
vector提供了insert函数,结合迭代器位置插入指定的元素。
如果迭代器位置越界,会抛出异常。
//初始化vector对象 vector<int> v1(10); //在指定的位置插入元素10的拷贝 v1.insert(v1.begin() + 3, 10); //在指定的位置插入3个元素11的拷贝 v1.insert(v1.begin(), 3, 11); //遍历 for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl;总之,增加新元素时,如果超过当前的容量,则容量会自动扩充2倍,如果两倍容量仍不足,就扩大至足够大的容量。本图是直接在原空间基础上画的新增空间,其实要复杂得多,包括重新配置、元素移动、释放原始空间的过程。因此对vector容器而言当增加新的元素时,有可能很快完成(直接存在预留空间中),有可能稍慢(扩容后再放新元素);对修改元素值而言是较快的;对删除元素来说,若删除尾部元素较快,非尾部元素则稍慢,因为牵涉到删除后的元素移动。
利用vector编一个学生信息[学号(它是关键字)、姓名、性别、出生日期]管理类,有添加函数、查询函数(依据学好号查询),显示函数(对查询结果完成显示)。并编制测试函数测试。
(1)基本思想是要有一个基本信息类及该基本信息的集合类。对本题而言,基本信息类是学生类Student,集合类是StudCollect。 (2)Student类中定义了4个基本的成员变量及屏幕显示函数Display()。StudCollect定义了一个成员变量vector<Student> v,可看出本类是对学生集合对象的一个管理类,是实现集合管理类的根本所在。该类主要定义了Add(Student& s)函数及Student *Find(string strNO)函数。
#include <iostream> #include <vector> #include <string> using namespace std; class Student //学生类 { public: string m_strNO; //学号 string m_strName; //姓名 string m_strSex; //性别 string m_strDate; //出生日期 public: Student(string strNO, string strName,string strSex,string strDate): m_strNO(strNO),m_strName(strName),m_strSex(strSex),m_strDate(strDate){} void Display(){ cout <<m_strNO<<"\t"<<m_strName<<"\t"<<m_strSex<<"\t"<<m_strDate<<endl; } }; class StudCollect { vector<Student> m_vStud; public: void Add(Student& s){ m_vStud.push_back(s); } Student* Find(string strNO){ bool bFind = false; for(int i=0; i<m_vStud.size(); i++) { Student& s = m_vStud.at(i); if(s.m_strNO == strNO) { bFind = true; break; } } Student *s = NULL; if(bFind) s = &m_vStud.at(i); return s; } }; void main() //仿真测试程序 { Student s1("1001","zhangsan","boy","1985-10-10"); Student s2("1002","lisi","boy","1984-6-10"); Student s3("1003","wangwu","boy","1985-11-15"); StudCollect s; s.Add(s1),s.Add(s2),s.Add(s3); Student *ps = s.Find("1002"); if(ps) ps->Display(); }