【STL】浅析Vector

概述

本文是对vector容器的基本操作初探。

STL组件的相互关系请阅读【STL】STL六大组件概述。Array基础操作请阅读【STL】浅析Array

Vector是封装了动态大小数组的顺序容器。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,vector是一个能够存放任意类型的动态数组。

本文首先介绍了vector容器特点,然后在Code示例以注释方式介绍vector初始化、vector.size()、vector.front()、vector.back()、vector.data()等操作。具体操作演示请阅本文Code示例

std::vector特点

1、std::vector就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。

2、std::vector本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。

3、std::vector分配空间策略,vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。


vector添加元素时,分配的a byte的空间,不够用情况下,将会另外开辟一个2a byte的空间,继续添加元素。


4、std::vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。

5、std::vector与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。

上述特点参考了博客【C++】STL——vector的简单介绍

Code示例

以Code示例进行介绍vector最基础的操作。

#include <vector>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio>
#include <iostream>
#include <ctime>
#include <algorithm>

using namespace std;
long VALUE = 1000000;

namespace jj02 {
    void test_vector(long& value) 
    {
        cout << "\ntest_vector().................\n";
        
        //初始化vector  <>代表模板初始化为string
        vector<string> c;
        char buf[10];

        clock_t timeStart = clock();

        for (long i = 0; i < value; ++i) {
            //异常处理 防止value太大,导致无法分配内存空间
            try {
                snprintf(buf, 10, "%d", rand());
                //.push_back() 从vector容器数据后端添加元素
                //例如vector 为  [* * * * * * *].push_back(%) = [* * * * * * * %]
                //vector 增长原理  [vector 当分配的a字节的空间,不够用时。
                //                  将会另外开辟一个2a字节的空间,继续添加元素]
                c.push_back(string(buf));
            }
            catch (exception& p) {
                cout << "i=" << i << " " << p.what() << endl;
                abort();
            }
        }

        cout << "milli-seconds : " << (double)(clock() - timeStart) / CLOCKS_PER_SEC * 1000 << "ms" << endl;
        cout << "vector.max_size()=" << c.max_size() << endl;           //返回容器能够容纳的最大元素数量,注意,这个数量实际上取决于操作系统和编译器的限制
        cout << "vector.size()= " << c.size() << endl;                  //vector的元素数量
        cout << "vector.front()= " << c.front() << endl;                //vector的第一个元素
        cout << "vector.back()= " << c.back() << endl;                  //vector的最后一个元素
        cout << "vector.data()= " << c.data() << endl;                  //vector的第一个元素的地址
        cout << "vector.capacity()= " << c.capacity() << endl << endl;  //vector当前能够容纳的元素数量。注意,capacity()函数返回的是容器分配内存能够容纳的元素数量的数量,而不是元素的实际数量。

        string target = get_a_target_string();
        {
            timeStart = clock();
            //STL容器采用左闭右开 [  ) 的形式存储
            //vector.begin()返回首元素迭代器 .end()返回末尾元素再后以为的迭代器
            //find() 函数用于查找容器中第一个等于指定值的元素,并返回指向该元素的迭代器。
            //如果在容器中找不到指定值,则返回指向容器末尾[.end()]的迭代器。
            auto pItem = find(c.begin(), c.end(), target);
            cout << "std::find(), milli-seconds : " << (double)(clock() - timeStart) * 1000 / CLOCKS_PER_SEC << "ms" << endl;

            if (pItem != c.end())
                cout << "fount, " << *pItem << endl << endl;
            else
                cout << "not fount!" << endl << endl;
        }

        {
            timeStart = clock();
            /*sort(begin, end, cmp),其中begin为指向待sort()的数组的第一个元素的指针,
            end为指向待sort()的数组的最后一个元素的下一个位置的指针,cmp参数为排序准则,cmp参数可以不写,
            如果不写的话,默认从小到大进行排序。
            sort()并非只是普通的快速排序,除了对普通的快速排序进行优化,它还结合了插入排序和堆排序。
            根据不同的数量级别以及不同情况,能自动选用合适的排序方法。
            */
            sort(c.begin(), c.end());
            cout << "sort(), milli-seconds : " << (double)(clock() - timeStart) * 1000 / CLOCKS_PER_SEC << "ms" << endl;

            timeStart = clock();
           /*bsearch
           使用二分查找,查找一个被排序过的数组s
           void *bsearch(const void *key, const void *base,
                    size_t nmemb, size_t size,
                    int (*compar)(const void *, const void *));

           key: 指向要查找的元素
           base : 指向被查找的数组
           nmemb : 被查找数组的大小
           size : 被查找数组元素的大小
           int (*compar)(const void*, const void*) : 比对的函数*/
            string* pItem = (string*)::bsearch(&target, (c.data()), c.size(), sizeof(string), compareStrings);
            cout << "bsearch(), milli-seconds : " << (double)(clock() - timeStart) * 1000  / CLOCKS_PER_SEC  << "ms" << endl;

            if (pItem != NULL)
                cout << "found, " << *pItem << endl << endl;
            else
                cout << "not found! " << endl << endl;
        }
    }
}


int main()
{
    jj02::test_vector(VALUE);

    return 0;
}


运行结果:

参考文献:

STL源码剖析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值