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;
}

2.迭代器

vector<int>::iterator it = v.beggin();
while(it!=v.end())
{
	cout<< *it;
	it++;
}

3.范围for

for(auto i = v)
{
	cout<<i;
}

范围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

四、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<<' ';
}

五、排序

排序不需要我们自己去写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;

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

//引头文件#include <functional>
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>);

六、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)

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

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

九、二维数组vector<vector>

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;
	}

在这里插入图片描述

十、总结

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

在这里插入图片描述

  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猪皮兄弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值