• vector详解以及一些问题(C++)


    🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
    在这里插入图片描述

    一、 vector介绍

    在这里插入图片描述

    在 c++ 中,vector 是一个十分有用的容器。 它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。vector 是同一种类型的对象的集合,每个对象都有一个对应的整数索引值。 和 string 对象一样,标准库将负责管理与存储元素相关的内存。 我们把 vector 称为容器,是因为它可以包含其他对象。

    在这里插入图片描述
    之前就说过,类模板必须显示写模板类型

    二、三种遍历方式

    1.普通

    int main()
    {
    	vector<int> v;
    	v.push_back(1);
    	v.push_back(2);
    	v.push_back(3);				
    	v.push_back(4);
    	for(int i=0;i<v.size();i++)
    	{
    		cout<<v[i];
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.迭代器

    vector<int>::iterator it = v.beggin();
    while(it!=v.end())
    {
    	cout<< *it;
    	it++;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.范围for

    for(auto i = v)
    {
    	cout<<i;
    }
    
    • 1
    • 2
    • 3
    • 4

    范围for底层也是用的迭代器,不过每次会自动++

    三、find

    像vector,ist这样的类,不提供find,因为没有意义,相同值的索引可能有多个
    所以,如果 想用find,就用库里面的,在algorithm里
    在这里插入图片描述
    需要传递迭代区间和要搜索的值
    find的实现只能用!=,不能用<,因为对于string,vector,空间连续,还可以这样干,但是list这些,空间不连续,<根本不能用

    InputIterator find(InputIterator first,InputIterator last,const T& val);
    //find找到了返回的是一个迭代器,没有找到的话返回end(),找到了返回pos位置的迭代器
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    vector<int>::iterator pos=find(v.begin(),v.end(),3);
    //然后进行对这个位置的一些操作,比如insert,erase
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    四、insert,erase

    insert和erase就是对某个特定的位置进行插入和删除操作,一般配合algorithm里的find进行使用,这个特定的位置需要是一个迭代器,因为传值是不能确定位置的

    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    vector<int>::iterator pos=find(v.begin(),v.end(),3);
    if(pos!=v1.end())//因为没找到才返回的end,end是最后一个数据的下一个位置
    {
    	v1.insert(pos,30)}
    for(auto i : v)
    {
    	cout<< i<<' '; 
    }
    pos = find(v1.begin(),v1.end(),3);
    //之前3的位置已经被修改了,每次操作都要重新find
    if(pos != v1.end())//没找到返回end(),end()是最后一个数据的下一个位置
    {
    	v1.erase(pos);
    }
    for(auto i :v)
    {
    	cout<< i<<' ';
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    五、排序

    排序不需要我们自己去写qsort了,标准库里面有sort,传迭代区间就行,但它默认排的升序
    在这里插入图片描述

    vector<int > v;
    push_back(10);
    push_back(2);
    push_back(32);
    push_back(4);
    push_back(5);
    push_back(1);
    push_back(9);
    
    sort(v1.begin(),v1.end());
    for(auto i : v)
    {
    	cout<<i<<" ";
    }
    cout<<endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    想排降序,就需要用到仿函数,现在这里就只需要会用就行

    //引头文件#include 
    greater<int> gt;
    less<int> ls;
    sort(v.begin(),v.end(),gt);>降序
    sort(v.begin(),v.end(),ls);<升序
    ----------------------------------
    //最后一个参数是匿名对象也行
    sort(v.begin(),v.end(),greater<int>);
    sort(v.begin(),v.end(),less<int>);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    六、string str和vector v的差别

    1.str最后有\0,而v判断是否越界访问
    2.str支持+=,而v不支持
    3.find str可以find串,v只能find一个
    4.比较大小,to_string >> << stoX等等
    在这里插入图片描述
    所以,vector无法替代,string

    七、push_back

    在这里插入图片描述
    1.引用,因为除了int,double这些,还有string,string是通过new出来的,如果val是传值拷贝,那么就涉及到深拷贝的问题,代价很大
    2.const 引用
    a.不改变,加const起保护作用
    b.因为可能传参传一个strV.push_back(“zhupi”));"zhupi"是存在常量区的,也就是代码段,具有常性,所以,为了避免出现权限放大的问题,所以const引用,传参的类型判断和下面的隐式转换是没有关系的

    strV.push_back(“zhupi”);为什么可以直接传"zhupi",因为string里有一个构造函数string(const char*str){};有一个隐式类型的转换,但是因为直接传"zhupi"比较方便,所以就没有阻止这种隐式类型转换(explicit就可以组织发生隐式类型转换)

    八、范围for中建议传引用

    for(auto str:strV)
    
    • 1

    会把strV[i]的值拷贝给str,也会发生拷贝构造,所以,也会出现深拷贝的问题,所以范围for也建议用引用

    for(const auto & str: strV)
    //不加const,就可以对其进行修改
    
    • 1
    • 2

    九、二维数组vector

    vector二维数组,也是通过arr[][]进行随机访问的,空间地址连续
    在这里插入图片描述
    需要注意的是,vector中的resize,只能够去开它所对应的空间,也就是说,如果你想开辟一个arr[10][10]的一个数组,那么写法如下

    vector<vector<int>> vv;
    	vv.resize(10);
    	for (int i = 0; i < vv.size(); i++)
    	{
    		vv[i].resize(10);
    	}
    	//上面在进行开空间
    	for (int i = 0; i < vv.size(); i++)
    	{
    		for (int j = 0; j < vv[i].size(); j++)
    		{
    			vv[i][j] = 1;
    		}
    	}
    	for (int i = 0; i < vv.size(); i++)
    	{
    		for (int j = 0; j < vv[i].size(); j++)
    		{
    			cout << vv[i][j] << " ";
    		}
    		cout << endl;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    十、总结

    向量(vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。感谢大家的支持!

    在这里插入图片描述

  • 相关阅读:
    一文解决Linux系统下安装并配置Java环境变量
    MINA架构DEMO
    vue中关于表单的常用学习
    25、ESP8266的AP模式跟Station模式代码实现
    LED球泡灯IC:PWM调光的LED恒流驱动芯片,适用于宽输入电压范围的应用
    12306购票辅助工具
    想要创建百度百科词条怎么做?
    数据挖掘题目:根据规则模板和信息表找出R中的所有强关联规则,基于信息增益、利用判定树进行归纳分类,计算信息熵的代码
    图神经网络
    OPengl学习(二)——opengl环境搭建
  • 原文地址:https://blog.csdn.net/zhu_pi_xx/article/details/126719929