开发者

C++ vector容器缩小capacity问题

目录
  • C++ vector容器缩小capacity
  • C++ vector容器的常用用法
    • 一、不带参数
    • 二、带参数
  • 总结

    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容器会根据你传入的数据数量进行自动扩展,总是比你存入的数据多一些。

    www.devze.com

    但是有一些时候我们不需要那么多开辟好的空间,对于数据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
      qmqJYDUmhc  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 获取容器的元素个数

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

    capacity 获取容器的大小

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

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

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

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

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

    assign 赋值玩法

    • 第一种玩法 会改变原来vector中的元素内存大小

    将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;
    	/********************************javascript****************************************************************/
    	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.jsassign(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;www.devze.com
    	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容器常用的函数已经列出来了,剩下还有很多个不常用的,就不说明了,需要用到的话,再另行百度吧!

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜