本文原创发表地址为:http://www.cppblog.com/kusamba/archive/2010/09/16/126786.html,转载请保留原链接,谢谢!
std::vector作为顺序容器,具有如下特点:
/************************************************************************* vector* 1, 顺序存储,内部数据结构为数组* 2, 使用之前调用reserve()预分配元素数目,可提高性能* 3, insert/erase操作效率低,跟被操作元素在vector中的位置成正比* 在末尾增加或删除元素所需时间与元素数目无关,* 在中间或开头增加或删除元素所需时间随元素数目呈线性变化* 4, insert/erase操作将有可能导致vector内存重新分配,iterator失效* 5, 时间复杂度:* 随机索引访问[index]: O(1)* 查找:O(n)* by Kusamba@126.com http://www.cppblog.com/kusamba*/技术要点:
1,加载头文件
#include <vector>
using namespace std;
2,预分配内存, 调用reserve函数
3, 插入对象,使用push_back或[index]
4, insert/erase 如何避免iterator失效
代码如下:
1 /************************************************************************
2 * vector
3 * 1, 顺序存储,内部数据结构为数组
4 * 2, 使用之前调用reserve()预分配元素数目,可提高性能
5 * 3, insert/erase操作效率低,跟被操作元素在vector中的位置成正比
6 * 在末尾增加或删除元素所需时间与元素数目无关,
7 * 在中间或开头增加或删除元素所需时间随元素数目呈线性变化
8 * 4, insert/erase操作将有可能导致vector内存重新分配,iterator失效
9 * 5, 时间复杂度:
10 * 随机索引访问[index]: O(1)
11 * 查找:O(n)
12 */
13
14 /**
15 * 谓词表达式
16 */
17 struct sComplexObj
18 {
19 int nID;
20 char szNickName[32];
21 };
22 bool Equal_ID(sComplexObj obj)
23 {
24 return obj.nID == 4 ? true : false;
25 }
26
27 /**
28 * 测试代码
29 */
30 void vector_test()
31 {
32 vector<int> vInt;
33
34 /**
35 * reserve : 预分配空间
36 * capacity: 获取预分配空间数目
37 * size : 当前元素个数
38 */
39 int nCapacity = 0, nSize = 0;
40 nCapacity = vInt.capacity();
41
42 vInt.reserve(10);
43 nSize = vInt.size();
44
45 /**
46 * insert
47 */
48 for (int i = 0; i < 10; ++i)
49 {
50 vInt.push_back(i + 1);
51 }
52 for (int i = 0; i < 10; ++i)
53 {
54 vInt[i] = vInt[i] * 2;
55 }
56
57 // insert: 在4倍数元素的后面插入一个元素,值为该元素的2倍
58
59 // 错误的做法
60 ////for (vector<int>::iterator it = vInt.begin(); it != vInt.end(); ++it)
61 ////{
62 //// if (*it % 4 == 0)
63 //// {
64 //// vInt.insert(it, *it * 2);-->it失效
65 //// //重新分配了空间,it和begin(), end()均失效
66 //// }
67 ////}
68
69 // 利用计数插入
70 for (int i = 0; i < vInt.size(); ++i)
71 {
72 if (vInt[i] % 4 == 0)
73 {
74 vInt.insert(vInt.begin() + i + 1, vInt[i] * 2);
75 i += 1;
76 }
77 }
78 // 利用iterator以及insert返回的被插入元素的位置
79 for (vector<int>::iterator it = vInt.begin(); it != vInt.end(); ++it)
80 {
81 if (*it % 3 == 0)
82 {
83 it = vInt.insert(it + 1, *it * 2);//获取当前插入元素的位置
84 }
85 }
86
87 /**
88 * erase
89 */
90 for (vector<int>::iterator it = vInt.begin(); it != vInt.end(); )
91 {
92 if (*it % 2 == 0)
93 {
94 it = vInt.erase(it);//返回end()或后一个元素的新位置
95 }
96 else
97 {
98 ++it;
99 }
100 }
101
102 //使用谓词 只能删除一次
103 vInt.erase(remove(vInt.begin(), vInt.end(), 4));
104
105 //对于复杂对象,还可以使用remove_if算法
106 {
107 vector<sComplexObj> vComplexObj;
108 for (int i = 0; i < 10; ++i)
109 {
110 sComplexObj obj;
111 obj.nID = i;
112 sprintf_s(obj.szNickName, "ID_%06d", i);
113 vComplexObj.push_back(obj);
114 }
115 vComplexObj.erase(remove_if(vComplexObj.begin(), vComplexObj.end(), Equal_ID));
116 }
117
118 /**
119 * traverse
120 */
121 printf("print vInt method1: ");
122 for (int i = 0; i < vInt.size(); ++i)
123 {
124 printf("%d ", vInt[i]);
125 }
126 printf("\n");
127
128 printf("print vInt method2: ");
129 for (vector<int>::iterator it = vInt.begin(); it != vInt.end(); ++it)
130 {
131 printf("%d ", *it);
132 }
133 printf("\n");
134 }