当前位置:   article > 正文

学习笔记——vector容器_vector 取值

vector 取值
  1. vector容器简介——动态数组

  • vector是将元素置于一个动态数组加以管理的容器。

  • vector可用vector[idx]或者vector.at(idx)函数取值。

  • vector在<尾部>插入&删除元素非常快;在<头部>插入&删除元素的时间成本为O(n);在<中间>插入&删除元素也较慢。

  1. vector对象

vector采用模板类实现,其对象的类型遵循其指定类型。

2.1 vector对象的构造
vetcor对象的默认构造:
  1. //vetcor对象的默认构造
  2. vector<int> v; //一个存放int的vector容器
  3. vector<float> v; //一个存放float的vector容器
  4. vector<string> v; //一个存放string的vector容器
  5. class CA{};
  6. vector<CA> v; //一个存放 CA对象 的vector容器
  7. vector<CA*> v; //一个存放 CA对象指针 的vector容器
vetcor对象的带参数构造:
  1. //vetcor对象的带参数构造
  2. //第1种:vector(begin,end); 用两个指针
  3. int arr[] = {1,2,3,4,5};
  4. //将以上数组全部存入vector
  5. //知识点1:数组名字代表数组首地址,即该指针指向数组第一个元素
  6. //注意!因为是左闭右开区间,所有右边要比最大索引大
  7. vector<int> v1(arr, arr+5);
  8. //第2种:vector(n,elem);
  9. vector<int> v2(3,10); //存储3个10
  10. //第3种:vector(const vector &vec); 用一个容器对象
  11. vector<int> v3(v1); //v3和v1一样
2.2 vector对象的赋值
  1. void test_vector02() {
  2. vector<int> v2(10,10);
  3. for (int i = 0; i < v2.size(); i++) {
  4. cout << v2[i] << " ";
  5. }
  6. cout << endl;
  7. int arr[] = { 1,2,3,4,5 };
  8. v2.assign(arr, arr + 5);
  9. for (int i = 0; i < v2.size(); i++) {
  10. cout << v2[i] << " ";
  11. }
  12. cout << endl;
  13. }

运行程序后输出:

可见:vector.assign(beg,end)函数先清空原对象,再赋值

  1. vector的大小

说明:当容器为空,vector.size()返回值为0。

vector.resize(num):容器变长,用默认值0填充多的位置;容器变长,截掉多的元素。

  1. vector的索引

Q:vec[idx]如果下标越界可能会导致程序异常终止,但对于初学者,很难看出是因为越界运行停止的。那么如何确保越界一定会提醒呢?

A:使用vec.at(idx)函数,一旦越界一定报错。注意!只是报错,运行也会停止,但会让我们知道为什么停止。

  1. vector的插入&删除

5.1 在末尾插入&删除:
  • v.push_back(x);//在容器末尾插入

  • v.pop_back();//在容器末尾删除

5.2 在中间插入&删除:
  • v.insert(position, x);//在position位置插入x,返回新的<迭代器>

  • v.insert(position, n, x);//在position位置插入n个x,无返回值

  • v.insert(position, beg, end);//在position位置插入[beg, end)区间的数据,无返回值

注意:以上position, beg, end都为<指针>,而非<索引下标>

  1. //容器中插入普通数组
  2. void test_vector051() {
  3. vector<int> v5(3, 10);
  4. int a[] = { 1,2,3,4,5 };
  5. //10 10 10->10 2 3 10 10
  6. v3.insert(v5.begin() + 1, a + 1, a + 3);
  7. for (int i = 0; i < v5.size(); i++) {
  8. cout << v5[i] << " ";
  9. }
  10. cout << endl;
  11. }

运行程序后输出:

  1. //容器中插入容器
  2. void test_vector052() {
  3. vector<int> v3(3, 10);
  4. int a[] = { 1,2,3,4,5 };
  5. vector<int> v4(a, a + 5);
  6. //10 10 10->10 2 3 10 10
  7. v3.insert(v3.begin() + 1, v4.begin()+1, v4.begin() + 3);
  8. for (int i = 0; i < v3.size(); i++) {
  9. cout << v3[i] << " ";
  10. }
  11. cout << endl;
  12. }
  1. vector迭代器

6.1 vector迭代器的使用

每种容器都定义了一对名为begin()end()的函数,用于返回迭代器。

  1. class Person {
  2. public:
  3. //构造函数,用列表赋值
  4. Person(int age, int id) :age(age),id(id){}
  5. public:
  6. int age;
  7. int id;
  8. };
  9. void test_vector061() {
  10. //创建类型是Person类的容器v6
  11. vector<Person> v6;
  12. Person p1(23, 2112), p2(22, 2111), p3(22, 2110);
  13. v6.push_back(p1);
  14. v6.push_back(p2);
  15. v6.push_back(p3);
  16. //构造一个迭代器对象ite
  17. vector<Person>::iterator ite;
  18. ite = v6.begin();
  19. //用迭代器遍历容器v6中的所有元素
  20. for (ite; ite != v6.end(); ite++) {
  21. cout << (*ite).age << " " << (*ite).id << " ";//(*ite)取*,即指向对象
  22. }
  23. cout << endl;
  24. for_each
  25. //vector<Person>::iterator pb = v.begin();
  26. //vector<Person>::iterator pe = v.end();
  27. //for_each(pb, pe, Print);
  28. }
6.2 vector迭代器的失效
插入时失效:
  1. void test_vector062() {
  2. vector<int> v;
  3. v.push_back(1);
  4. v.push_back(2);
  5. v.push_back(3);
  6. v.push_back(4);
  7. vector<int>::iterator t = v.begin() + 3;
  8. cout << *t << endl;
  9. //要想使运行不终止,t = v7.insert(t, 8); 因为insert()返回新的<迭代器>
  10. v.insert(t, 8);
  11. cout << *t << endl;
  12. }

运行程序,在输出一个4之后(即执行完line 9),程序就报错:

这是因为编译器在运行时,insert()操作是新开辟了一个空间,并将原来的值复制过去。但<迭代器>t仍在原位置,故报错。

Summary:若在使用insert(pos, elment)函数时,用到了<迭代器>,那么一定要给<迭代器>重新赋值insert(pos, elment)函数的返回值

删除时失效:
  1. void test_vector062_2() {
  2. vector<int> v = { 1,2,3,3,3,4,5,6 };
  3. vector<int>::iterator it;
  4. for (it = v.begin(); it != v.end(); it++)
  5. {
  6. if (*it == 3)
  7. v.erase(it);
  8. }
  9. for (it = v.begin(); it != v.end(); it++)
  10. cout << *it << " ";
  11. cout << endl;
  12. }

运行程序报错:

因为erase()函数是把后面的数据移到前面。用覆盖实现删除。

在G++里,erase()函数覆盖删除时,<迭代器>it依然在移动,就会造成只删除一半的3;

而在VS编译器里,利用erase()函数删除,会直接认为<迭代器>it失效。

为了不管什么编译器里都实现“删掉所有的3“的操作,应当改为:

  1. //不管什么编译器,都不会报错
  2. void test_vector062_3() {
  3. vector<int> v = { 1,2,3,3,3,4,5,6 };
  4. vector<int>::iterator it =v.begin();
  5. while (it != v.end())
  6. {
  7. if (*it == 3)
  8. it=v.erase(it);
  9. else
  10. it++;
  11. }
  12. for (it = v.begin(); it != v.end(); it++)
  13. cout << *it << " ";
  14. cout << endl;
  15. }

Summary:若在使用erase()函数时,为了保证<迭代器>不失效,一定要给<迭代器>重新赋值erase()函数的返回值

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/390849?site
推荐阅读
相关标签
  

闽ICP备14008679号