C++vector

        vector是表示可变大小数组的序列容器。

平时只关注第一个参数就行,第一个参数要考虑决定了vector里面存什么类型数组。第二个参数是空间配置器,即内存池。

 第一个是全缺省构造函数。第二第三是使用迭代器构造,第四个是拷贝构造。

下面用vector和迭代器试一下。

#include<iostream>
#include<vector>
using namespace std;
void test1()
{
	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]<<' ';
	}
	cout << endl;
	vector <int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it<<' ';
		it++;
	}
	cout << endl;
	
}
int main()
{
	test1();
	return 0;
}

 

问题:底下这两个有没有区别? 它俩都是char形数组,能不能用vector代替string? 

有区别:

  1. string后面有斜杠0。
  2. string支持用ASCII比较大小。而vector不支持,因为class T参数是个范型,不一定是char。
  3. 他俩接口不一样,sring可以+=,可以+=字符或字符串,vector没有必要也没有+=。

vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	cout << v.capacity() << endl;
	v.reserve(10);
	cout << v.capacity() << endl;
	v.reserve(6);
	cout << v.capacity() << endl;

  

不会缩容,比当前容量小时,不缩容,以空间换时间。

不能只退回一部分空间,可以用一个malloc开辟的空间不能free两次理解。

 

这里面的int就是下面的T,就是这个类型,val就是value_type这个类型的数据。val是要补的数据。

如果只写v.resize(8),那么第二个参数缺省值是什么呢?

value_type()相当于T(),如果是自定义类型,相当于调用它的构造函数。如果是内置类型,也可以拿构造函数理解。

那value_type()能不能改成0呢?

不能,因为一些类型不能直接用0初始化,比如日期类。

  • 下面代码实现一下
void test2()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.resize(8);
	for (int i = 0;i < v.size();i++)
	{
		cout << v[i] << ' ';
	}
	cout << endl;
	v.resize(10, 2);
	for (int i = 0;i < v.size();i++)
	{
		cout << v[i] << ' ';
	}
	cout << endl;
	v.resize(3);
	for (int i = 0;i < v.size();i++)
	{
		cout << v[i] << ' ';
	}
	cout << endl;
}

  • 下面看一下vector是如何扩容的。
void test3()
{
	vector<int> v;
	int sz = v.capacity();
	for (int i = 0;i < 100;i++)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed:" << sz << endl;
		}
	}
}

VS2019大约是1.5倍扩容。

Linux上是2倍扩容。 

为什么一般是扩2倍?

因为2倍通常比较合适,如果扩少了,会导致频繁扩容,扩多了,会造成空间浪费。

 如果不断扩容,后面不一定有足够空间原地扩容,所以可以用reserve先申请空间。

构造时开空间也可以,但没有reserve灵活。

力扣https://leetcode-cn.com/problems/pascals-triangle/description/        (杨辉三角链接)

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
         vector<vector<int>> vv;

         vv.resize(numRows);
         for(int i=0;i<numRows;i++)
         {
            vv[i].resize(i+1,0);
            vv[i][0]=vv[i][i]=1;
         }
           for(int i=0;i<numRows;i++)
         {
             for(int j=0;j<i+1;j++)
             {
                 if(vv[i][j]==0)
                 {
                     vv[i][j]=vv[i-1][j-1]+vv[i-1][j];
                 }
             }
         }
         return vv;
    }
};

reserve和resize是string和vector独有的。

比如list它俩没有意义。

这两个是同一个size(),只不过上面的是权限平移,下面是权限缩小。

 

 但operator[]是有两个版本的。

改不了。 出现错误。

 

改得了。 

 

 只读接口函数,只提供const就可以,如果只写的接口函数(push_back),必须提供非const,可读可写的接口函数,就需要提供const和非const接口(operator[])。

at可读性不强。at是成员函数,operator[]是运算符重载。

  • 它和operator还有没有区别?
  • 它俩在访问下标大于v.resize时,at会抛异常,而operator[]会断言报错。

 []用断言检查里面数字是否小于size。

此程序报错

断言检查

 operator[]加了个断言检查不能让i大于v.size()。这是规定。

可以这么用,用push_back

 at这么写报错,其实是报异常,其实异常能被捕获。

这样可以捕获异常


断言比较暴力,直接终止程序。 

 断言缺点是,release版本不起作用。


assign是个赋值,它不是用对象赋值,而是靠需求赋值。比如用n个对象赋值,

之前的值被覆盖。

 

vector支持传迭代器。

 

 它其实是个模板。

 

 因为v是<int>,所以它取的是ASCII码

迭代器的加减

string的insert大部分这个参数是下标,而vector是迭代器。


数据结构核心的部分是增删查改,

vector

想要在第二个位置头插可以移动迭代器。

因为vector是连续空间,所以加2可以指向第3个字符位置

 vector没有自己的find函数,用的是std中的。

 

体现了迭代器区间左闭右开的重要性,因为last不是成员值,失败可以返回last。 

例子

 

 因为string更多的是要找子串,所以string里面自己有一个find。

string中的find返回的是下标。

 左闭右开。

 

 

 clear不会影响capacity。只会清空数据。

 为什么vector有专门swap?

 因为我有时会这样用

 这样如果vector没有的话,就会走到算法库里面的swap,算法库里面的swap要进行深拷贝,会降低效率。

为了避免这种情况,vector自己有一个swap。

缩容函数。以空间换时间,c++11提供,这个要少用。

 

 不允许在原先空间处只释放一部分内存。不允许分段释放,只能整体释放。

所以下面这样不会缩容。 

 

 

 

 设计理念就是不动空间,不缩容。空间换时间。

缩容一般是开辟一个新空间,释放旧空间。

所以这个就是个反面函数。 

 

 

 当我们确定较大空间我们不需要时,会选择这个函数。

stl3.0源码网盘链接
提取码:0s5t

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

南种北李

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

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

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

打赏作者

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

抵扣说明:

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

余额充值