zoukankan      html  css  js  c++  java
  • STL之vector容器

    摘要:本文主要介绍了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 }
  • 相关阅读:
    C/S架构引用Lodop 如何在C#调用web打印控件Lodop
    Lodop打印设计(PRINT_DESIGN)里的快捷键
    Lodop打印控件中PRINT_INITA()和PRINT_PAGESIZE()宽高
    LODOP打印控件关联输出各内容
    如何判断使用的是Lodop还是C-Lodop
    Lodop代码设置打印机等信息后 设置预览可重选
    Lodop打印控件输出页码(超文本和纯文本页码)
    PhotoShop不用魔棒、钢笔 建立较平整的选区 P进电脑屏幕里
    uniq命令详解
    sort命令详解
  • 原文地址:https://www.cnblogs.com/lzy820260594/p/11377448.html
Copyright © 2011-2022 走看看