1.vector的插入
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1[0] = 10; //可修改值
2.vector的三种遍历
void test_vector1()
{
//遍历
//下标
for(int i = 0; i < v1.size(); i++)
{
cout << v1[i] << " ";
}
cout << endl;
//迭代器
vector<int>::iterator it = v1.begin();
while(it != v1.end())
{
cout << *it << " ";
++it;
}
cout << endl;
//范围for
for(auto& e : v1)
{
cout << e << " ";
}
cout << endl;
}
3.利用const迭代器遍历打印
void PrintVector(const vector<int>& v)
{
//const对象使用const迭代器进行遍历打印
vector<int>::const_iterator it = v.begin();
while(it != v.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
4.利用函数模板定义vector变量
注意:在VS中不用加关键字typename,在Linux中编译需要添加上,不然会报错,主要就是不同编译器会认为这个对象的含义不一样。可以看文章报错情况
template <class T>
void PrintVector(const vector<T>& v)
{
//const对象使用const迭代器进行遍历打印
typename vector<T>::const_iterator it = v.begin();
while(it != v.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
void test_vector2()
{
vector<int> v1;
vector<int> v2(10,0);
vector<int> v3(v2.begin(),v2.end());
string s("hello world");
vector<char> v4(s.begin(),s.end());
vector<string> v5;
string s3("sort");
v5.push_back(s3);
v5.push_back(string("erase")); //利用匿名函数
//推荐使用
v5.push_back("insert");
PrintVector(v2);
PrintVector(v3);
PrintVector(v4);
PrintVector(v5);
}
5.反向迭代器
vector<string> copy(v5);
PrintVector(copy);
//vector<string>::reverse_iterator rit = copy.rbegin();
auto rit = copy.rbegin();
while (rit != copy.rend())
{
cout << *rit << " ";
++rit;
}
cout << endl;
6.list的迭代器遍历
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
list<int>::iterator it = lt.begin();
while (it != lt.end())
{
cout << *it << " ";
++it;
}
cout << endl;
7.验证vector的增容方式
//验证vector的增容方式
void test_vector3()
{
size_t sz;
std::vector<int> foo;
foo.resize(100); //知道需要100个空间,先开100,就不会增容
sz = foo.capacity();
std::cout << "make foo grow:\n";
for(int i = 0; i < 100; i++)
{
foo.push_back(i);
if(sz != foo.capacity())
{
sz = foo.capacity();
std::cout << "capacity changed: " << sz << '\n';
}
}
}
若不加:foo.resize(100);
结果如下:是成2倍增容(Linux),VS下是1.5倍增容
8. vector的插入与删除
141 void test_vector5()
142 {
143 vector<int> v;
144 v.push_back(1);
145 v.push_back(2);
146 v.push_back(3);
147 v.push_back(4);
148
149 for(auto e:v)
150 {
151 cout << e << " ";
152 }
153 cout << endl;
154
155 //头插
156 v.insert(v.begin(),0);
157
158 for(auto e:v)
159 {
160 cout << e << " ";
161 }
162 cout << endl;
163
164 //删除
165 v.erase(v.begin());
166
167 for(auto e:v)
168 {
169 cout << e << " ";
170 }
171 cout << endl;
172 }
9.迭代器失效
例子:按上面插入的例子来说明:
pos是在插入30之前给的值,插入30以后,可以认为pos就失效,pos失效有两种可能:
(1)pos的意义变了,插入数据以后,pos不再是指向3,而是30,导致erase(pos)没有达到删除3的目的,删除的是30
怎么解决迭代器 失效:可以增加引用,最后pos = pos + 1;
175 //在3的前面插入一个30
176 vector<int>::iterator pos = find(v.begin(),v.end()> ,3);//需要左闭右开
177 if(pos != v.end())
178 {
179 v.insert(pos,30);
180 }
181
182 for(auto e:v)
183 {
184 cout << e << " ";
185 }
186 cout << endl;
187
188 //删除3
189 v.erase(pos);
190
191 for(auto e:v)
192 {
193 cout << e << " ";
194 }
195 cout << endl;
(2)可能会出现崩溃,出现野指针(pos是野指针)
原因:因为insert出现增容以后,pos位置指向空间已经释放,pos已经是野指针
解决方案:迭代器在insert后面使用就失效了
pos = find(v.begin(),v.end(),3);//需要左闭右开
188 //删除3
189 v.erase(pos);
190
191 for(auto e:v)
192 {
193 cout << e << " ";
194 }
195 cout << endl;
迭代器失效的另一个例子:删除v中所有的偶数
下面例子会出错:3会相当于没有检查,若3改为30,仍会保留,删除2后,后面的数字会依次向前移动填补,就会出现漏检的情况。
203 void test_vector5()
204 {
205 vector<int> v;
206 v.push_back(1);
207 v.push_back(2);
208 v.push_back(3);
209 v.push_back(4);
210 v.push_back(5);
211 v.push_back(6);
212
213
214 //迭代器失效另外的方式:删除v中所有的偶数
215 vector<int>::iterator it = v.begin();
216 while(it != v.end())
217 {
218 if(*it % 2 == 0)
219 {
220 v.erase(it);
221 }
222 ++it;
223 }
解决方案:
//迭代器失效另外的方式:删除v中所有的偶数
215 vector<int>::iterator it = v.begin();
216 while(it != v.end())
217 {
218 if(*it % 2 == 0)
219 {
220 //erase(it)以后,it失效,不能++
221 //erase会返回删除位置it的下一个位置
222 v.erase(it);
223 }
224 else{
225 ++it;
226 }
227 }
228 for(auto e:v)
229 {
230 cout << e << " ";
231 }
232 cout << endl;
233
234 }