zoukankan      html  css  js  c++  java
  • STL中vector的用法

    原本以为自己掌握了vector,但其实只是掌握了vector的访问,特别是删除操作返回的是一个迭代器,却容易和Python的remove()直接删除元素混淆,没有理解透彻,因此在这里总结一下vector的基本用法。

    vector应该是STL种最常用的容器了,可以当做数组来看待,只不过vector的元素更丰富,不仅仅是数据元素,还可以是结构体

    1、vector的创建和初始化

    vector <double> v;//创建一个double类型的vector
    vector <int> v2(5);//创建一个含有5个元素的int型vector,初始值默认为0
    vector <int> v3(4,7);//创建一个含有4个元素的int型vector,初始值都为7
    

    当然也可以通过在尾部添加元素来初始化

    vector <double> v;
    v.push_back(3.5);
    v.push_back(4.9);
    v.push_back(1.5);//其中v[0] = 3.5 v[1] = 4.9 v[2] = 1.5
    

    2、vector的元素遍历

    vector <double> v;
    v.push_back(3.5);
    v.push_back(4.9);
    v.push_back(1.5);
    //下标访问
    for(int i = 0; i < v.size();i++)
    {
    	cout << v[i] << endl;
    }
    //const迭代器访问
    for(vector <double>::const_iterator it = v.begin(); it !=v.end();it++)
    {
    	cout << *it << endl;
    }
    //非const迭代器访问
    for(vector <double>::iterator it = v.begin(); it !=v.end();it++)
    {
    	cout << *it << endl;
    }
    //逆序访问,同样分为const和非const
    for(vector <double>::reverse_iterator it = v.rbegin(); it !=v.rend();it++)
    {
    	cout << *it << endl;
    }
    

    说明一下,其中的const和非const迭代器在访问元素时没有区别,只是非const迭代器可以通过*it = value来改变vector元素的值

    3、vector的插入操作

    v.insert(v.begin()+2,5); //在索引为2(从0开始)的位置插入元素5
    v.insert(v.begin(),2,3);//在索引为0的位置插入2个值为3的元素
    

    4、vector的删除

    v.erase(v.begin()+i);//删除索引为i的元素
    v.erase(vec.begin()+i,vec.end()+j);删除区间[i,j-1];区间从0开始
    v.pop_back();//删除尾部元素 v.clear();//删除所有元素

    举个例子,删除double类型的vector中与指定值key相等的元素,并统计个数,其实统计个数可以用 int n = count(v.begin(),v.end(),key) 返回的就是个数,count头文件是<alogrithm>

    vector <double> v;
    v.push_back(3.5);
    v.push_back(4.9);
    v.push_back(1.5);
    v.push_back(3.5);
    v.push_back(3.5);
    v.push_back(4.9);
    v.push_back(3.5);
    double key = 3.5;
    const double MIN = 0.00000001;
    //索引删除
    for(int i =0; i<v.size();i++)
    {
    	if((v[i] - key < MIN) && (v[i] -key > -MIN)) //double类型,需要定义一个精度
    	{
    		v.erase(v.begin()+i);
    		i--;//假设[2,3,4]删除元素3,其索引为2,删除3后,元素4成了索引2对应的值,所以减一
    		cnt++;
    	}
    }
    //或者用迭代器删除
    for(it = v.begin();it != v.end();)
    {
    	
    	if((*it - key < MIN) && (*it -key > -MIN)) 
    	{
    		it = v.erase(it); //删除函数返回的是下一个元素的迭代器
    		cnt++;
    	}
    	else
    	{
    		it++;
    	}	
    
    }
    
    //使用算法删除,remove函数后会获取删除key后迭代器的位置,此时位于新序列的结尾,该位置距离原始序列的结尾还差删除的key的个数的距离,因此再earse最后几个空位置
    v.erase(remove(v.begin(),v.end(),key),v.end());
    

      

    5、相关的算法

    reverse(vec.begin(),vec.end()); //将元素翻转
    sort(vec.begin(),vec.end()); //默认升序排列
    bool cmp(const int &m, const int &n)
    {
    	return a > b;
    }
    sort(vec.begin(),vec.end(),cmp); //根据cmp排序,这里是
    

    6、vector的内存分配

    vector其实维护着三个指针

    template <typename T>
    class vector
    {
    	...
    	private:
    	T* first;
    	T* last;
    	T* end;
    };
    

      由于没法上图片,这里就简单解说一下吧,创建一个vector时,三个指针均指向同一个位置,当用push_back添加元素时,first指向首元素,last指向尾元素,而end则指向vector.capacity,也就是可以容纳的最大元素个数的索引位置,而这个容量是成指数增加的,添加第1个元素,可容纳1个元素,然后添加第2个元素,此时容器大小为2,然后添加第3个元素,此时容器大小会增加2,变为4,而不是3,添加第4个元素时,由于容器大小为4,可容纳,此时容器大小不变,当添加第5个元素时,容器大小就增加到8了,我理解这是一种策略,不然每次添加一个元素,容器都增加一个空间,增加空间实际上是将原来的内存空间拷贝到了另一个内存空间,过度频繁拷贝导致效率低,所以才成指数级增加,尽管这样,但是拷贝还是很多,效率还是挺低的,不过用起来很方便。所以可以理解为first到last之间的元素为vector实际存储的元素,first到end是vector的可用空间大小。

  • 相关阅读:
    Git 的版本库创建和修改
    appnium框架以及源码研究
    根据图片的URL生成PDF保存到本地(前台js)
    根据图片的URL生成PDF保存到服务器上(后台C#实现)
    麻烦的控件只读
    利用Javascript生成txt文本文件
    KendoUI AngularJS Bootstrap
    给Grid动态添加列和添加样式
    linq 分组求和的一般方法
    KendoUi学习之旅 Combobox的使用
  • 原文地址:https://www.cnblogs.com/xqn2017/p/9152537.html
Copyright © 2011-2022 走看看