C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++ vector容器缩小capacity

C++ vector容器缩小capacity问题

作者:白白白白白kkk

这篇文章主要介绍了C++ vector容器缩小capacity问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

C++ vector容器缩小capacity

vector容器是动态存储的,跟数组不同,定义vector的时候不需要声明容器的capacity。

首先说明一点,size是小于等于capacity的,一旦size超过了capacity,整个vector容器会“另辟居所”重新开辟更多的空间,这样也就造成了vector容器首地址发生改变。

下面是容器的size和capacity的关系:

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    vector<int> v0;
    for (int i = 0; i < 100;i++)
    {
        v0.push_back(i);
    }
    cout << "v0 capacity is " << v0.capacity() << endl;//128
    cout << "v0 size is " << v0.size() << endl;//100
    vector<int> v1;
    for (int i = 0; i < 10000;i++)
    {
        v1.push_back(i);
    }
    cout << "v1 capacity is " << v1.capacity() << endl;//16384
    cout << "v1 size is " << v1.size() << endl;//10000
    return 0;
}

可以看出,vector容器会根据你传入的数据数量进行自动扩展,总是比你存入的数据多一些。

但是有一些时候我们不需要那么多开辟好的空间,对于数据size是确定的,这时候可以用匿名vector交换vector

先介绍一下vector的内置函数swap(),只贴核心代码了:

    vector<int> v1;
    v1.reserve(10000);//预设一个空间大小
    for (int i = 0; i < 100;i++)
    {
        v1.push_back(i);
    }
    cout << "v1 capacity is " << v1.capacity() << endl;//10000
    cout << "v1 size is " << v1.size() << endl;//100
    vector<int> v2;
    v2.reserve(5000);
    for (int i = 0; i < 50;i++)
    {
        v2.push_back(i);
    }
    cout << "v2 capacity is " << v2.capacity() << endl;//5000
    cout << "v2 size is " << v2.size() << endl;//50
    v2.swap(v1);
    cout << "v1 capacity is " << v1.capacity() << endl;//5000
    cout << "v1 size is " << v1.size() << endl;//50
    cout << "v2 capacity is " << v2.capacity() << endl;//10000
    cout << "v2 size is " << v2.size() << endl;//100

reserve()函数是预设一个大小,不会使其反复开辟,当然如果后续超过这个预设值,vector容器还是会自动开辟的。

上面的代码旨在展示swap()函数交换的是一整个容器,包含的是容器的capacity和数据的size。

交换缩小vector:

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    vector<int> v1;
    for (int i = 0; i < 10000;i++)
    {
        v1.push_back(i);
    }
    cout << "v1 capacity is " << v1.capacity() << endl;//16384
    cout << "v1 size is " << v1.size() << endl;//10000
    v1.resize(3);
    cout << "v1 capacity is " << v1.capacity() << endl;//16384
    cout << "v1 size is " << v1.size() << endl;//3
    vector<int> temp(v1);
    cout << "temp capacity is " << temp.capacity() << endl;//3
    cout << "temp size is " << temp.size() << endl;//3
    temp.swap(v1);
    cout << "v1 capacity is " << v1.capacity() << endl;//3
    cout << "v1 size is " << v1.size() << endl;//3
    vector<int>(v1).swap(v1);//匿名容器,用后自动销毁。除了没有自己的变量名,其他的一样
    cout << "v1 capacity is " << v1.capacity() << endl;//3
    cout << "v1 size is " << v1.size() << endl;//3
    return 0;
}

上面的代码可以看出:

一个vector如果是通过拷贝构造的,那么他的size和capacity相同,且等同于被拷贝的那个容器的size。

结合上面第二点的发现,swap函数是一整个交换的,这样理论上就可以用temp和v1换,最后使v1的size=capacity,节省了空间。另外,使用匿名容器更加高效方便。

C++ vector容器的常用用法

vector可以说是一个动态数组,它可以存储任何类型的数据,包括类!

使用vector需包含头文件 #include< vector > .

一、不带参数

// 定义了一个int类型的容器
vector<int> v1;
// 定义了一个double类型的容器
vector<double> v2;

注意事项:容器可以使用数组方式获取它的值 和 给它赋值,但是得注意越界!

例如:不可以使用数组方式给他赋值,因为容器并没有给他分配内容空间:

vector<int> v1;
// 不可以使用数组方式给他赋值,因为容器并没有给他分配内容空间
v1[0] = 1;	// error
// 可以使用数组方式给他赋值:
vector<int> v2(10);
v2[0] = 1;	// 正确
v2[11] = 11; // 错误,越界

二、带参数

1.定义了一个int类型的容器,定义时指定给他分配十个元素的空间

// 定义了一个int类型的容器,定义时指定给他分配十个元素的空间
vector<int> v1(10);

默认10个元素都是零值。

2.定义时指定10个元素的内存,同时给所有元素赋值666

vector<int> v3(10, 666);

3.定义时可以使用其他容器来初始化自己

vector<int> v1(5, 666);
// 定义时可以使用其他容器来初始化自己
vector<int> v2(v1);	// v1 和 v2 相等

4.// 也可以使用 返回迭代器 的方式将一个容器的元素全都赋值给自己

vector<int> v1(5, 666);
vector<int> v2(v1.begin(), v1.end());

5.begin 和 end 返回来的就是一个指针迭代器,所以可以进行加减操作,指向其他元素的位置

vector<int> v1(5, 666);
// 将v1的元素从第三个元素到最后的元素赋值给v2
vector<int> v2(v1.begin() + 2, v1.end());

6.可以使用数组来初始化容器

int Array[5] = {1, 2, 3, 4, 5};
// 将数组元素1,2,3,4给容器赋初值
vector<int> v1 = (Array, Array+3);

size 获取容器的元素个数

vector<int> v1;
v1.size();

capacity 获取容器的大小

vector&lt;int&gt; v1;v1.capacity();

begin 获取容器第一个元素的迭代器

vector<int> v1(10, 666);
v1.begin();

end 指向容器最后一个元素的下一个位置的迭代器

vector<int> v1(10, 666);
v1.end();

assign 赋值玩法

将v1元素修改为5个,并且赋值888

vector<int> v1(10);
v1.assign(5, 888);	// 打印结果5个888

将容器v2的10个1赋值给v1,使得v1和v2相等

vector<int> v1(5);
vector<int> v2(10, 1);
v1.assign(v2.begin(), v2.end());	// 打印结果10个1

将数组的所有元素都赋值给v1

int Array[5] = { 9, 8, 7, 6, 5 };
vector<int> v1;
v1.assign(Array, Array + 4);	// 打印结果9,8,7,6,5

将v1所有元素赋值给v2

vector<int> v1(10, 1);
vector<int> v2;
v2 = v1;	// 打印结果10个1

resize 将容器缩小和变大

一、把容器元素缩小

vector<int> v1(10);
v1.resize(5);	// 缩小长度为5

二、把容器扩大时,并给增加的元素赋值

vector<int> v1(5);
v1.resize(8, 111);	// 扩充v1容器的大小为8,后续新增加的使用111赋值

三、把容器扩大,不给增加的元素赋值

vector<int> v1(5);
v1.resize(15);

empty 判断容器是否为空

为空返回true,为假返回false

vector<int> v1(5);
if (v1.empty() == NULL) {
	cout << "v1为空!" << endl;
}

push_back 尾部添加一个元素

vector<int> v1;
v1.push_back(1);	// 在尾部增加要给1

pop_back 尾部删除一个元素

vector<int> v1(10);
v1.pop_back();	// 在尾部删除一个元素

at 和数组使用方式差不多

给第一个元素赋值1

vector<int> v1(10);
v1.at(0) = 1; 

打印输出容器里的所有元素

cout << "v1的所有元素:";
for (int i = 0; i < v1.size(); i++) {
	cout << v1.at(i) << ", ";
}

front 获取容器的第一个元素

vector<int> v1(10);
v1.front();
// 也可以使用他们赋值
v1.front() = 111;	// 给第一个元素赋值111

back 获取容器的最后一个元素

vector<int> v1(10);
v1.back();
// 也可以使用他们赋值
v1.back() = 222;	// 给最后一个元素赋值222

insert 元素的插入

vector<int> v1(10);
// 往第一个元素的位置插入一个5
v1.insert(v1.begin(), 5);
// 从第三个元素位置开始插入5个222
v1.insert(v1.begin() + 2, 5, 222);
vector<int> v2(3, 111);
// 从第二个元素开始插入v2的所有值
v1.insert(v1.begin() + 1, v2.begin(), v2.end());

erase 与 clear 元素删除

vector<int> v1(10);
// 删除第一个元素
v1.erase(v1.begin());
// 删除第一个到第三个元素
v1.erase(v1.begin(), v1.begin() + 3);
// 删除全部元素
v1.clear();

汇总代码:

#include <iostream>
#include <Windows.h>
#include <vector>
using namespace std;
// 不带参数的
void text1(void) {
	vector<int> v1;
	cout << "v1的元素个数:";
	cout << v1.size() << endl;
	cout << "v1容器的大小:";
	cout << v1.capacity() << endl;
	v1.push_back(1);
	v1.push_back(2);
	cout << endl << "v1插入两个元素后:" << endl;
	cout << "v1的元素个数:";
	cout << v1.size() << endl;
	cout << "v1容器的大小:";
	cout << v1.capacity() << endl;
	/*
	注意:
		不可以使用数组方式给他赋值,因为容器并没有给他分配内容空间:
			vector<int> v;
			v[0] = 1;	// error
	*/
}
// 带参数的
void text2(void) {
	vector<int> v2(10);	// 定义时指定给他分配十个元素的空间
	cout << "v2的元素个数:";
	cout << v2.size() << endl;
	cout << "v2容器的大小:";
	cout << v2.capacity() << endl;
	// 里面默认的值全为零
	cout << "v2里面的元素为:" << endl;
	vector<int>::iterator it = v2.begin();
	for (; it != v2.end(); it++) {
		cout << *it << ", ";
	}
	cout << endl;
	/*
	可以使用数组方式给他赋值:
		vector<int> v(10);
		v[0] = 1;	// 正确
	*/
	v2[0] = 1;	// 正确
	v2[1] = 2;
	cout << "v2里面的元素为:" << endl;
	it = v2.begin();
	for (; it != v2.end(); it++) {
		cout << *it << ", ";
	}
	cout << endl;
	/************************************************************************************************/
	vector<int> v3(10, 666);	// 定义时指定10个元素的内存,同时给所有元素赋值666
	cout << "v3里面的元素为:" << endl;
	it = v3.begin();
	for (; it != v3.end(); it++) {
		cout << *it << ", ";
	}
	cout << endl;
	/************************************************************************************************/
	vector<int> v4(v3);	// 定义时可以使用其他容器来初始化自己
	cout << "v4里面的元素为:" << endl;
	it = v4.begin();
	for (; it != v4.end(); it++) {
		cout << *it << ", ";
	}
	cout << endl;
	/************************************************************************************************/
	vector<int> v5(v2.begin(), v2.end());	// 也可以使用该种方式将v2的元素全都赋值给自己
	cout << "v5里面的元素为:" << endl;
	it = v5.begin();
	for (; it != v5.end(); it++) {
		cout << *it << ", ";
	}
	cout << endl;
	/************************************************************************************************/
	vector<int> v6(v2.begin() + 1, v2.end());	// begin返回来的就是一个指针迭代器,所以可以进行加1操作,指向下一个元素
	cout << "v6里面的元素为:" << endl;
	it = v6.begin();
	for (; it != v6.end(); it++) {
		cout << *it << ", ";
	}
	cout << endl;
	/************************************************************************************************/
	int text[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	vector<int> v7(text, text + 5);	// 可以使用这种方式获取数组的值初始化自己(1,2,3,4,5)
	cout << "v7里面的元素为:" << endl;
	it = v7.begin();
	for (; it != v7.end(); it++) {
		cout << *it << ", ";
	}
	cout << endl;
}
// vector容器赋值assign玩法
void assign(void) {
	vector<int> v1(5);
	// 第一种玩法	会改变原来vector中的元素内存大小
	v1.assign(3, 8);
	cout << "玩法一:" << endl;
	vector<int>::iterator it = v1.begin();
	for (; it != v1.end(); it++) {
		cout << *it << ", ";
	}
	cout << endl;
	// 第二种玩法,使用迭代器赋值
	vector<int> v2(10, 1);
	v1.assign(v2.begin(), v2.end());
	cout << "玩法二:" << endl;
	it = v1.begin();
	for (; it != v1.end(); it++) {
		cout << *it << ", ";
	}
	cout << endl;
	// 第三种玩法,使用指针赋值
	int Array[5] = { 9, 8, 7, 6, 5 };
	v1.assign(Array, Array + 2);
	cout << "玩法三:" << endl;
	it = v1.begin();
	for (; it != v1.end(); it++) {
		cout << *it << ", ";
	}
	cout << endl;
	// 第四种玩法,使用赋值运算符重载
	vector<int> v3;
	v3 = v1;
	cout << "玩法四:" << endl;
	it = v3.begin();
	for (; it != v3.end(); it++) {
		cout << *it << ", ";
	}
	cout << endl;
}
// resize将容器缩小和变大 与 empty判断容器是否为空
void text3(void) {
	vector<int> v1(10);
	// 一、把容器元素缩小
	cout << "v1的元素个数:" << v1.size() << endl;
	v1.resize(5);	// 调整他的元素个数为5
	cout << "v1的元素个数:" << v1.size() << endl;
	// 二、把容器扩大时,并给增加的元素赋值
	v1.resize(8, 111);	// 扩充v1容器的大小为8,后续新增加的使用111赋值
	cout << "v1的元素个数:" << v1.size() << endl;
	cout << "v1的所有元素:";
	for (int i = 0; i < v1.size(); i++) {
		cout << v1[i] << ", ";
	}
	cout << endl;
	// 三、把容器扩大,不给增加的元素赋值
	v1.resize(15);
	cout << "v1的元素个数:" << v1.size() << endl;
	cout << "v1的所有元素:";
	for (int i = 0; i < v1.size(); i++) {
		cout << v1[i] << ", ";
	}
	cout << endl;
	cout << endl << endl << "---empty---" << endl;
	// 判断容器是否为空
	vector<int> v2;
	if (v2.empty()) {
		cout << "v2为空!" << endl;
	}
}
// 尾部添加和删除
void text4(void) {
	vector<int> v1;
	cout << "v1的元素个数:" << v1.size() << endl;
	// 尾部添加一个元素
	v1.push_back(666);
	cout << "v1的元素个数:" << v1.size() << endl;
	// 尾部删除一个元素
	v1.pop_back();
	cout << "v1的元素个数:" << v1.size() << endl;
}
// at 与 front 与 back
void text5(void) {
	vector<int> v1(10);
	// 可以使用at修改容器里面的值,返回的是一个引用
	v1.at(0) = 888;
	// 和数组方式差不多
	v1[1] = 999;
	// 输出
	cout << "v1的所有元素:";
	for (int i = 0; i < v1.size(); i++) {
		cout << v1[i] << ", ";
	}
	cout << endl;
	// 也可以使用at输出
	cout << "v1的所有元素:";
	for (int i = 0; i < v1.size(); i++) {
		cout << v1.at(i) << ", ";
	}
	cout << endl;
	// 他们返回的都是一个引用
	cout << "第一个元素:" << v1.front() << endl;
	cout << "最后一个元素:" << v1.back() << endl;
	// 也可以使用他们赋值
	v1.front() = 111;
	v1.back() = 222;
	cout << "v1的所有元素:";
	for (int i = 0; i < v1.size(); i++) {
		cout << v1.at(i) << ", ";
	}
	cout << endl;
}
// insert 元素的插入
void text6(void) {
	vector<int> v1(10);
	// 往第一个元素的位置插入一个5
	v1.insert(v1.begin(), 5);
	// 从第三个元素位置开始插入5个222
	v1.insert(v1.begin() + 2, 5, 222);
	vector<int> v2(3, 111);
	// 从第二个元素开始插入v2的所有值
	v1.insert(v1.begin() + 1, v2.begin(), v2.end());
	cout << "v1的所有元素:";
	for (int i = 0; i < v1.size(); i++) {
		cout << v1.at(i) << ", ";
	}
	cout << endl;
}
// 元素删除
void text7(void) {
	vector<int> v1(10);
	// 删除第一个元素
	v1.erase(v1.begin());
	// 删除第一个到第三个元素
	v1.erase(v1.begin(), v1.begin() + 3);
	// 删除全部元素
	v1.clear();
}
int main(void) {
	//text1();
	//text2();
	//assign();
	//text3();
	//text4();
	//text5();
	//text6();
	//text7();
	system("pause");
	return 0;
}

注意:

vector容器常用的函数已经列出来了,剩下还有很多个不常用的,就不说明了,需要用到的话,再另行百度吧!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文