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

    一、vector容器概念

    • vector是将元素置于一个动态数组(或可变数组)中加以管理的容器,连续内存空间,大小会根据元素个数进行自动增长。
    • vector可以随机存取元素(支持索引值直接存取, 用[]操作符或at()方法,这个等下会详讲)。
    • vector容器是一个单口容器,vector尾部添加或移除元素非常快速。但是在中部或头部插入元素或移除元素比较费时。

    二、vector动态增长基本原理

    当插入新元素时,如果空间不足,那么vector会重新申请更大的一块内存空间,将原空间数据拷贝到新空间,释放旧空间的数据,再把新元素插入新申请空间。

    三、vector常用API

    1、vector构造函数

    2、vector常用赋值操作

    3、vector大小操作

    注意:resize 若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

    4、vector数据存取操作

    5、vector插入和删除操作

    6、巧用swap缩减空间

    由于vector的内存占用空间只增不减,比如你首先分配了10,000个字节,然后erase掉后面9,999个,留下一个有效元素,但是内存占用仍为10,000个。所有内存空间是在vector析构时候才能被系统回收。empty()用来检测容器是否为空的,clear()可以清空所有元素。但是即使clear(),vector所占用的内存空间依然如故,无法保证内存的回收。

    7、reserve预留空间

    如果知道容器大概要存储的元素个数,那么可以用reserve预留空间。

    总结:vector是个动态数组,当空间不足的时候插入新元素,vector会重新申请一块更大的内存空间,将旧空间数据拷贝到新空间,然后释放旧空间。vector是单口容器,所以在尾端插入和删除元素效率较高,在指定位置插入,势必会引起数据元素移动,效率较低。

    四、案例

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    #include <vector>
    using namespace std;
    
    void PrintVector(vector<int>& v)
    {
        for (vector<int>::iterator it = v.begin();it != v.end();it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    //初始化
    void test01()
    {
        vector<int> v1;//默认构造
    
        int arr[] = { 10,20,30,40 };
        vector<int> v2(arr, arr + sizeof(arr) / sizeof(int));
        vector<int> v3(v2.begin(), v2.end());
        vector<int> v4(v3);
    
        PrintVector(v2);//10 20 30 40
        PrintVector(v3);//10 20 30 40
        PrintVector(v4);//10 20 30 40
    }
    
    //常用赋值操作
    void test02()
    {
        //构造函数
        int arr[] = { 10,20,30,40 };
        vector<int> v1(arr, arr + sizeof(arr) / sizeof(int));
    
        //成员方法
        vector<int> v2;
        v2.assign(v1.begin(), v1.end());
    
        //重载=号运算符
        vector<int> v3;
        v3 = v2;
    
        //构造函数
        int arr1[] = { 100,200,300,400 };
        vector<int> v4(arr1, arr1 + sizeof(arr1) / sizeof(int));
    
        PrintVector(v1);//10 20 30 40
        PrintVector(v2);//10 20 30 40
        PrintVector(v3);//10 20 30 40
        PrintVector(v4);//100 200 300 400
    
        cout << "------------------" << endl;
    
        v4.swap(v1);//v4与v1交换,交换原理:只是把内部指向数据的指针进行了交换
    
        PrintVector(v1);//100 200 300 400
        PrintVector(v2);//10 20 30 40
        PrintVector(v3);//10 20 30 40
        PrintVector(v4);//10 20 30 40
    
    }
    
    //大小操作
    void test03()
    {
        int arr[] = { 10,20,30,40 };
        vector<int> v1(arr, arr + sizeof(arr) / sizeof(int));
    
        cout << "size:" << v1.size() << endl;//size:4
    
        if (v1.empty())
        {
            cout << "空!" << endl;
        }
        else
        {
            cout << "不空!" << endl;//不空
        }
    
        PrintVector(v1);//10 20 30 40
        v1.resize(2);
        PrintVector(v1);//10 20
        v1.resize(4);
        PrintVector(v1);//10 20 0 0
        v1.resize(6,1);
        PrintVector(v1);//10 20 0 0 1 1
    
        for (int i = 0;i < 100;i++)
        {
            v1.push_back(i);
        }
        //容量capacity>=元素的个数size
        cout << "元素的个数size:" << v1.size() << endl;//元素的个数size:106
        cout << "容量capacity:" << v1.capacity() << endl;//容量capacity:141
    }
    
    //vector存取数据
    void test04()
    {
        int arr1[] = { 100,200,300,400 };
        vector<int> v4(arr1, arr1 + sizeof(arr1) / sizeof(int));
    
        //[]取值与at()取值的区别:索引值越界时,at抛异常,[]不抛异常
        for (int i = 0;i < v4.size();i++)
        {
            //cout << v4[i] << " ";
            cout << v4.at(i) << " ";//100 200 300 400        
        }
        cout << endl;
    
        cout << "front:" << v4.front() << endl;//front:100
        cout << "back:" << v4.back() << endl;//back : 400
    }
    
    //vector插入和删除操作
    void test05()
    {
        vector<int> v;
        v.push_back(10);
        v.push_back(20);
        //头插法
        v.insert(v.begin(), 30);
        v.insert(v.end(), 40);
    
        v.insert(v.begin()+2, 100);//在这里可以用v.begin()+2,是因为:vector支持随机访问
        //支持数组下标的,一般都支持随机访问
        //迭代器可以直接 +某个数 或 -某个数 的操作
        PrintVector(v);//30 10 100 20 40
    
        //删除
        v.erase(v.begin());
        PrintVector(v);//10 100 20 40
        v.erase(v.begin()+1,v.end());
        PrintVector(v);//10
        v.clear();
        cout << "size:" << v.size() << endl;//size:0
    }
    
    //巧用swap缩减空间
    void test06()
    {
        //vector添加元素 它会自动增长,删除元素的时候,不会自动减少
        vector<int> v;
        for (int i = 0;i < 10000;i++)
        {
            v.push_back(i);
        }
    
        cout << "size:" << v.size() << endl;//size:10000
        cout << "capacity:" << v.capacity() << endl;//capacity:12138
    
        v.resize(10);
        cout << "size:" << v.size() << endl;//size:10
        cout << "capacity:" << v.capacity() << endl;//capacity:12138
    
        //收缩空间:
        //swap技法就是通过交换函数swap(),使得vector离开其自身的作用域,
        //从而强制释放vector所占的内存空间。
        //vector<int>(v):用v去初始化匿名对象,匿名对象会根据v的实际元素个数初始化它自己,
        //然后匿名对象的指针指向与v的指针指向交换,随后匿名对象自动释放
        vector<int>(v).swap(v);//或者v.swap(vector<int>(v));
        cout << "size:" << v.size() << endl;//size:10
        cout << "capacity:" << v.capacity() << endl;//capacity:10
    
    }
    
    void test07()
    {
        //reserve 预留空间
        int num = 0;//统计自动增长的次数
        int* address = NULL;
    
        vector<int> v;
        //如果知道容器大概要存储的元素个数,那么可以用reserve预留空间
        v.reserve(10000);
        for (int i = 0;i < 10000;i++)
        {
            v.push_back(i);
            if (address != &(v[0]))//通过判断vector内存的首地址是否发生变化可知道是否申请了新的内存
            {
                address = &(v[0]);
                num++;
            }
        }
        cout << "num:" << num << endl;
    
    }
    
    int main(void)
    {
        //test01();
        //test02();
        //test03();
        //test04();
        //test05();
        //test06();
        test07();
    
        return 0;
    }
  • 相关阅读:
    在tortoiseSVN上将trunk的代码merge到branch上去
    ajax提交后完全不进入action直接返回错误
    Eclipse "IOConsole updater" has encounter a problem
    jquery判断checkbox是否选中及改变checkbox状态[转]
    JS的Data类型格式化(转)
    Eclipse内置Tomcat的配置
    firebug下载时出现there was an error loading firebug
    Mac下Tomcat启动时乱码
    ibatis插入数据后返回自增长的主键
    给Mac下的iTerm2增加配色
  • 原文地址:https://www.cnblogs.com/yuehouse/p/10088583.html
Copyright © 2011-2022 走看看