摘要:本文主要介绍了vector容器的使用,并且举例加以理解。
1、基本概念
1.1 什么是vector容器
简而言之,vector容器类似于数组,只不过相对数组而言,它有自己的优点:独特的空间配置策略。这样的空间配置策略有利于对空间的合理有效地利用。
1.2 vector迭代器
直接理解成指针,来操作vector容器中的内容。
1.3 vector数据结构
vector所采用的数据结构非常简单,线性连续空间,它以两个迭代器_Myfirst和_Mylast分别指向配置得来的连续空间中目前已被使用的范围,并以迭代器_Myend指向整块连续内存空间的尾端。
为了降低空间配置时的速度成本,vector实际配置的大小可能比客户端需求大一些,以备将来可能的扩充,这边是容量的概念。换句话说,一个vector的容量永远大于或等于其大小,一旦容量等于大小,便是满载,下次再有新增元素,整个vector容器就得另觅居所。
注意:所谓动态增加大小,并不是在原空间之后续接新空间(因为无法保证原空间之后尚有可配置的空间),而是一块更大的内存空间,然后将原数据拷贝新空间,并释放原空间。因此,对vector的任何操作,一旦引起空间的重新配置,指向原vector的所有迭代器就都失效了。这是程序员容易犯的一个错误,务必小心。
2、常用API操作
2.1 vector构造函数
vector<T> v | 采用模板实现类实现,默认构造函数 |
vector(v.begin(), v.end()) | 将v[begin(), end())区间中的元素拷贝给本身 |
vector(n, elem) | 构造函数将n个elem拷贝给本身 |
vector(const vector &vec) | 拷贝构造函数 |
2.2 vector常用赋值操作
assign(beg, end) | 将[beg, end)区间中的数据拷贝赋值给本身 |
assign(n, elem) | 将n个elem拷贝赋值给本身 |
vector& operator=(const vector &vec) | 重载等号操作符 |
swap(vec) | 将vec与本身的元素互换 |
2.3 vector大小操作
size() | 返回容器中元素的个数 |
empty() | 判断容器是否为空 |
resize(int num) |
重新指定容器的长度为num,若容器变长,则以默认值 填充新位置。如果容器变短,则末尾超出容器长度的元素被删除 |
resize(int num, elem) |
重新指定容器的长度为num,若容器变长,则以elem值填 充新位置。如果容器变短,则末尾超出容器长>度的元素被删除 |
capacity() | 容器的容量 |
reserve(int len) | 容器预留len个元素长度,预留位置不初始化,元素不可访问 |
2.4 vector数据存取操作
at(int idx) | 返回索引idx所指的数据,如果idx越界,抛出out_of_range异常 |
operator[] | 返回索引idx所指的数据,越界时,运行直接报错 |
front() | 返回容器中第一个数据元素 |
back() | 返回容器中最后一个数据元素 |
2.5 vector插入和删除操作
insert(const_iterator pos, int count,ele) | 迭代器指向位置pos插入count个元素ele |
push_back(ele) | 尾部插入元素ele |
pop_back() | 删除最后一个元素 |
erase(const_iterator start, const_iterator end) | 删除迭代器从start到end之间的元素 |
erase(const_iterator pos) | 删除迭代器指向的元素 |
clear() | 删除容器中所有元素 |
3、代码示例
1 #include<iostream> 2 #include <vector> 3 #include <list> 4 5 using namespace std; 6 7 void test01() { //本例主要反映vector的空间分配机制 8 vector<int>v; 9 for (int i=0;i<10;i++) 10 { 11 v.push_back(i); 12 cout << v.capacity() << endl; //容器的容量大小 13 } 14 } 15 16 void printVector(vector<int>&v) { 17 for (vector<int>::iterator it=v.begin();it!=v.end();it++) 18 { 19 cout << *it << " "; 20 } 21 cout << endl; 22 } 23 24 void test02() { 25 int array[] = { 1,2,3,4,5 }; 26 vector<int>v1(array, array + sizeof(array) / sizeof(int)); 27 vector<int>v2(v1.begin(), v1.end()); //确定始末位置,然后将数据放入容器 28 printVector(v1); 29 printVector(v2); 30 31 vector<int>v3(10,100); //前者是初始化值的数量,后者是初始化的值 32 printVector(v3); 33 34 vector<int>v4; 35 v4.assign(v3.begin(), v3.end()); 36 printVector(v4); 37 38 v4.swap(v2); 39 printVector(v4); 40 cout << "v4的大小" << v4.size() << endl; //值为5 41 if (v4.empty()) 42 { 43 cout << "v4空" << endl; 44 } 45 else 46 { 47 cout << "v4不空" << endl; 48 } 49 // 50 // v4.resize(10,-1); //12345后补充-1,前者是大小 51 // printVector(v4); 52 v4.resize(10); //12345后面默认补充0 53 printVector(v4); 54 v4.resize(3); 55 printVector(v4); 56 cout << "v4的大小"<<v4.size() << endl; 57 } 58 59 void test03() { //用swap收缩空间 60 vector<int>v; 61 for (int i=0;i<100000;i++) 62 { 63 v.push_back(i); 64 } 65 cout << "容量" << v.capacity() << endl; 66 cout << "大小" << v.size() << endl; 67 68 v.resize(3); //容量不变,大小改变 69 cout << "容量" << v.capacity() << endl; 70 cout << "大小" << v.size() << endl; 71 72 //以下的代码首先调用构造函数用v初始化了一个匿名对象(假设为x),该对象的容量为3(按照size来进行初始化),然后利用swap进行了指针交换, 73 //也就是让原有的v指向了容量大小为3的空间,而x指向了原来的容量很大的空间,当该行命令完成以后,编译器将匿名对象自动释放,以此压缩空间 74 vector<int>(v).swap(v); //容量和空间均变成3 75 cout << "v的容量" << v.capacity() << endl; 76 cout << "v的大小" << v.size() << endl; 77 } 78 79 void test04() { 80 vector<int>v; 81 82 v.reserve(100000); //空间预留,提前预留,那么num为1,否则会有多次 83 84 int *p = NULL; 85 int num = 0; 86 for (int i=0;i<100000;i++) 87 { 88 v.push_back(i); 89 if (p!=&v[0]) //判断是否指针指向了v[0]所在的位置,当没有预留时,因为不断重新配置空间,那么num会不断增加 90 { 91 p = &v[0]; 92 num++; 93 } 94 } 95 cout << num << endl; 96 } 97 98 void test05() { 99 vector<int>v; 100 v.push_back(10); 101 v.push_back(20); 102 v.push_back(30); 103 v.push_back(40); 104 105 cout << "第一个元素" << v.front() << endl; 106 cout << "最后一个元素" << v.back() << endl; 107 108 v.insert(v.begin()+1, 3, 100); //第一个参数是插入位置,第二个是插入个数,第三个是插入的具体值 109 printVector(v); 110 111 v.pop_back(); //尾数删除 112 printVector(v); 113 114 v.erase(v.begin()); //头数删除 115 printVector(v); 116 117 v.erase(v.begin(), v.end()); 118 v.clear(); //清空所有数据 119 if (v.empty()) 120 { 121 cout << "为空" << endl; 122 } 123 } 124 125 void test06() 126 { 127 //逆序遍历 128 vector<int>v; 129 for (int i = 0; i < 10; i++) 130 { 131 v.push_back(i); 132 } 133 134 // printVector(v); 135 //reverse_iterator 逆序迭代器 136 for (vector<int>::reverse_iterator it = v.rbegin(); it != v.rend(); it++) 137 { 138 cout << *it << " "; 139 } 140 cout << endl; 141 142 //vector迭代器是随机访问的迭代器 支持跳跃式访问 143 vector<int>::iterator itBegin = v.begin(); 144 itBegin = itBegin + 3; 145 //如果上述写法不报错,这个迭代器是随机访问迭代器 146 147 148 list<int>l; 149 for (int i = 0; i < 10; i++) 150 { 151 l.push_back(i); 152 } 153 list<int>::iterator lIt = l.begin(); 154 //lIt = lIt + 1; //不支持随机访问 155 156 } 157 158 159 int main() { 160 //test01(); 161 //test02(); 162 //test03(); 163 //test04(); 164 //test05(); 165 test06(); 166 system("pause"); 167 return 0; 168 }