【C++ 十二】C++ vector容器

C++ vector 容器



前言

本文包含vector基本概念、vector构造函数、vector赋值操作、vector容量和大小、vector插入和删除、vector数据存取、vector互换容器、vector预留空间。


1 vector 基本概念

功能: vector 数据结构和 数组非常相似,也称为 单端数组

vector 与普通数组区别: 不同之处在于数组是静态空间(大小固定),而 vector 可以 动态扩展

动态扩展:

(1)、并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间

(2)、vector 容器的迭代器是支持随机访问的迭代器
在这里插入图片描述

2 vector 构造函数

功能描述: 创建 vector 容器

函数原型:

(1)、vector<T> v; 采用模板实现类实现,默认构造函数

(2)、vector(v.begin(), v.end()); 将 v(begin(), end()) 区间中的元素拷贝给本身 (前闭后开)

(3)、vector(n, elem); 构造函数将 n 个 elem 拷贝给本身

(4)、vector(const vector &vec); 拷贝构造函数

// vector单端数组构造函数

#include <iostream>  // 包含标准输入输出流头文件
using namespace std;  // 使用标准命名空间

#include <vector>  // 使用vector单端数组容器,需包含头文件vector

void Fun_Print(vector<int>& v) {  // 使用引用方式&,传入vector<int>类型的形参v

	// vector<int>::iterator 拿到vector<int>这种容器的迭代器类型;每个容器都有一个专属的迭代器类型
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";  // it是个迭代器类型,本是是个指针,需使用*解引用
	}
	cout << endl;
}

void test() {

	// 1、默认构造,无参构造
	vector<int> v;

	// 2、将v开始迭代器到结束迭代器之间的元素,赋给v1
	vector<int> v1(v.begin(), v.end());

	// 3、将10个10拷贝给v
	vector<int> v2(10, 10);
	Fun_Print(v2);  // 调用Fun_Print()函数,遍历v2

	// 4、拷贝构造
	vector<int> v3(v2);
	Fun_Print(v3);  // 调用Fun_Print()函数,遍历v3
}

int main() {

	test();
	
	cout << endl;

	system("pause");  // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果

	return 0;  // 程序正常退出
}

在这里插入图片描述

3 vector 赋值操作

功能描述: 给 vector 容器进行赋值

函数原型:

(1)、vector& operator=(const vector &vec); 重载等号操作符

(2)、assign(beg, end); 将 [beg, end) 区间中的数据拷贝赋值给本身

(3)assign(n, elem); 将 n 个 elem 拷贝赋值给本身

// vector单端数组赋值

#include <iostream>  // 包含标准输入输出流头文件
using namespace std;  // 使用标准命名空间

#include <vector>  // 使用vector单端数组容器,需包含头文件vector

void Fun_Print(vector<int>& v) {  // 使用引用方式&,传入vector<int>类型的形参v

	// vector<int>::iterator 拿到vector<int>这种容器的迭代器类型;每个容器都有一个专属的迭代器类型
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";  // it是个迭代器类型,本是是个指针,需使用*解引用
	}
	cout << endl;
}

void test() {

	// 默认构造,无参构造
	vector<int> v;

	for (int i = 0; i < 10; i++) {
		v.push_back(i);  // 向容器中存放数据
	}

	// 1、赋值 operator=
	vector<int> v1 = v;
	Fun_Print(v1);

	// 2、使用assign()函数,将容器v起始迭代器到结束迭代器之间的元素赋给v1
	vector<int> v2;
	v2.assign(v.begin(), v.end());
	Fun_Print(v2);

	// 3、使用assign()函数,将10个'a'赋值给本身
	vector<int> v3;
	v3.assign(10, 'a');  // a - 97
	Fun_Print(v3);
}

int main() {

	test();
	
	cout << endl;

	system("pause");  // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果

	return 0;  // 程序正常退出
}

在这里插入图片描述

4 vector 容量和大小

功能描述: 对 vector 容器的容量和大小操作

函数原型:

(1)、empty(); 判断容器是否为空

(2)、capacity(); 容器的容量

(3)、size(); 返回容器中元素的个数

(4)、resize(int num);

1)、重新指定容器的长度为num,若容器变长,则以默认值填充新位置 (默认填充0)

2)、如果容器变短,则末尾超出容器长度的元素被删除

(5)、resize(int num, elem);

1)、重新指定容器的长度为num,若容器变长,则以elem值填充新位置

2)、如果容器变短,则末尾超出容器长度的元素被删除

// vector单端数组容量和大小

#include <iostream>  // 包含标准输入输出流头文件
using namespace std;  // 使用标准命名空间

#include <vector>  // 使用vector单端数组容器,需包含头文件vector

void Fun_Print(vector<int>& v) {  // 使用引用方式&,传入vector<int>类型的形参v

	// vector<int>::iterator 拿到vector<int>这种容器的迭代器类型;每个容器都有一个专属的迭代器类型
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";  // it是个迭代器类型,本是是个指针,需使用*解引用
	}
	cout << endl;
}

void test() {

	// 创建vector单端数组容器对象,并且通过模板参数指定容器中存放的数据的类型
	vector<int> v;

	// 向容器中放数据
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);

	// 1、empty()为真,代表容器为空
	if (v.empty()) {
		cout << "v容器为空" << endl;
	}
	else {
		cout << "v容器不为空" << endl;

		// 2、capacity()返回容器的容量
		cout << "v容器的容量为:" << v.capacity() << endl;

		// 3、size()返回容器的个数
		cout << "v容器的个数为:" << v.size() << endl;
	}

	cout << endl;

	// 4.1、resize()重新指定大小 ,若指定的更大,默认用0填充新位置
	v.resize(10);
	Fun_Print(v);  // 调用Fun_Print()函数,遍历容器v

	// 4.2、resize()重新指定大小 ,若指定的更小,超出部分元素被删除
	v.resize(5);
	Fun_Print(v);  // 调用Fun_Print()函数,遍历容器v

	cout << endl;

	// 5.1、resize()重新指定大小 ,若指定的更大,默认用0填充新位置;可以利用重载版本替换默认填充,默认填充10
	v.resize(10, 10);
	Fun_Print(v);  // 调用Fun_Print()函数,遍历容器v

	// 5.2、resize()重新指定大小 ,若指定的更小,超出部分元素被删除
	v.resize(5, 50);
	Fun_Print(v);  // 调用Fun_Print()函数,遍历容器v
}

int main() {

	test();
	
	cout << endl;

	system("pause");  // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果

	return 0;  // 程序正常退出
}

在这里插入图片描述

5 vector 插入和删除

功能描述: 对 vector 容器进行插入、删除操作

函数原型:

(1)、push_back(ele); 尾部插入元素 ele

(2)、pop_back(); 删除最后一个元素

(3)、insert(const_iterator pos, ele); 迭代器指向位置 pos 插入元素 ele (第一个参数为迭代器)

(4)、insert(const_iterator pos, int count,ele); 迭代器指向位置 pos 插入 count 个元素 ele

(5)、erase(const_iterator pos); 删除迭代器指向的元素

(6)、erase(const_iterator start, const_iterator end); 删除迭代器从 start 到 end 之间的元素

(7)、clear(); 删除容器中所有元素

// vector单端数组插入和删除

#include <iostream>  // 包含标准输入输出流头文件
using namespace std;  // 使用标准命名空间

#include <vector>  // 使用vector单端数组容器,需包含头文件vector

void Fun_Print(vector<int>& v) {  // 使用引用方式&,传入vector<int>类型的形参v

	// vector<int>::iterator 拿到vector<int>这种容器的迭代器类型;每个容器都有一个专属的迭代器类型
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";  // it是个迭代器类型,本是是个指针,需使用*解引用
	}
	cout << endl;
}

void test() {

	// 创建vector单端数组容器对象,并且通过模板参数指定容器中存放的数据的类型
	vector<int> v;

	// 1、push_back()向容器尾部插入元素
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	Fun_Print(v);  // 1 2 3

	// 2、pop_back()插入容器尾部元素
	v.pop_back();
	Fun_Print(v);  // 1 2

	// 3、insert()在容器的结束迭代器处,插入100
	v.insert(v.end(), 100);
	Fun_Print(v);  // 1 2 100

	// 4、insert()在容器的结束迭代器处,插入5个1000
	v.insert(v.end(), 5, 1000);  
	Fun_Print(v);  // 1 2 100 1000 1000 1000 1000 1000

	// 5、erase()删除容器开始迭代器中的元素
	v.erase(v.begin());
	Fun_Print(v);  // 2 100 1000 1000 1000 1000 1000

	// 6、erase()删除容器开始迭代器到结束迭代器中的元素
	v.erase(v.begin(), v.end());
	Fun_Print(v);  //

	// 7、clear()情况容器中的元素
	v.clear();
	Fun_Print(v);  //
}

int main() {

	test();

	system("pause");  // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果

	return 0;  // 程序正常退出
}

在这里插入图片描述

6 vector 数据存取

功能描述: 对 vector 中的数据的存取操作

函数原型:

(1)、at(int idx); 返回索引 idx 所指的数据

(2)、operator[i]; 返回索引 idx 所指的数据

(3)、front(); 返回容器中第一个数据元素

(4)、back(); 返回容器中最后一个数据元素

// vector单端数组容器数据存取

#include <iostream>  // 包含标准输入输出流头文件
using namespace std;  // 使用标准命名空间

#include <vector>  // 使用vector单端数组容器,需包含头文件vector

void test() {

	// 创建vector单端数组容器对象,并且通过模板参数指定容器中存放的数据的类型
	vector<int> v;

	for (int i = 0; i < 10; i++) {
		// push_back()向容器尾部插入元素
		v.push_back(i);
	}

	for (int i = 0; i < v.size(); i++) {
		// 1、at()返回索引i所指向的数据元素
		cout << v.at(i) << " ";  // 0 1 2 3 4 5 6 7 8 9
	}
	cout << endl;

	for (int i = 0; i < v.size(); i++) {
		// 2、[]返回容器下标i所指向的数据元素
		cout << v[i] << " ";  // 0 1 2 3 4 5 6 7 8 9
	}
	cout << endl;

	// 3、front()返回容器中的第一个数据元素
	cout << "v容器的第一个元素为: " << v.front() << endl;  // 0

	// 4、back()返回容器中的最后一个数据元素
	cout << "v容器的最后一个元素为: " << v.back() << endl;  // 9
}

int main() {

	test();

	system("pause");  // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果

	return 0;  // 程序正常退出
}

在这里插入图片描述

7 vector 互换容器

功能描述: 实现两个容器内元素进行互换

函数原型:

swap(vec); 将 vec 与本身的元素互换

// vector单端数组容器数据存取

#include <iostream>  // 包含标准输入输出流头文件
using namespace std;  // 使用标准命名空间

#include <vector>  // 使用vector单端数组容器,需包含头文件vector

void Fun_Print(vector<int>& v) {  // 使用引用方式&,传入vector<int>类型的形参v

	// vector<int>::iterator 拿到vector<int>这种容器的迭代器类型;每个容器都有一个专属的迭代器类型
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";  // it是个迭代器类型,本是是个指针,需使用*解引用
	}
	cout << endl;
}

void test() {

	// 创建vector单端数组容器对象,并且通过模板参数指定容器中存放的数据的类型
	vector<int> v;
	vector<int> v1;

	for (int i = 0; i < 10; i++) {
		// push_back()向容器尾部插入元素
		v.push_back(i);
		v1.push_back(i + 100);
	}

	cout << "容器互换前----------------------------" << endl;
	Fun_Print(v);
	Fun_Print(v1);

	v.swap(v1);  // swap()将v1容器中的数据元素与本身的数据元素进行互换

	cout << "容器互换后----------------------------" << endl;
	Fun_Print(v);
	Fun_Print(v1);
}

int main() {

	test();

	system("pause");  // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果

	return 0;  // 程序正常退出
}

在这里插入图片描述
实际用途:使用 swap 收缩内存空间

// vector单端数组容器数据存取

#include <iostream>  // 包含标准输入输出流头文件
using namespace std;  // 使用标准命名空间

#include <vector>  // 使用vector单端数组容器,需包含头文件vector

void Fun_Print(vector<int>& v) {  // 使用引用方式&,传入vector<int>类型的形参v

	// vector<int>::iterator 拿到vector<int>这种容器的迭代器类型;每个容器都有一个专属的迭代器类型
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";  // it是个迭代器类型,本是是个指针,需使用*解引用
	}
	cout << endl;
}

void test() {

	// 创建vector单端数组容器对象,并且通过模板参数指定容器中存放的数据的类型
	vector<int> v;
	
	for (int i = 0; i < 100000; i++) {
		// push_back()向容器尾部插入元素
		v.push_back(i);
	}

	cout << "v容器的容量为:" << v.capacity() << endl;  // 138255
	cout << "v容器的个数为:" << v.size() << endl;  // 100000

	v.resize(3);  // 重新指定个数

	cout << "指定个数后------------------------------" << endl;
	cout << "v容器的容量为:" << v.capacity() << endl;  // 138255
	cout << "v容器的个数为:" << v.size() << endl;  // 3

	// 收缩内存;使用swap收缩内存
	vector<int>(v).swap(v); //vector<int>(v)匿名对象;相当于利用v来创建了一个新的对象,其实是调用拷贝构造函数创建一个新对象(x);实际无名(x);按照v来做初始化操作,会按v目前所用的元素个数来初始化匿名对象(x)的大小;所以匿名对象最开始大小和容量都为3;使用swap,容器交换后,匿名对象会进行回收

	// 互换元素的本质:相当于指针的交换
	// 匿名对象特点:当前行代码执行完后,匿名对象立即被回收,系统回收

	cout << "收缩内存后------------------------------" << endl;
	cout << "v容器的容量为:" << v.capacity() << endl;  // 3
	cout << "v容器的个数为:" << v.size() << endl;  // 3
}

int main() {

	test();

	system("pause");  // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果

	return 0;  // 程序正常退出
}

在这里插入图片描述

在这里插入图片描述

8 vector 预留空间

功能描述: 减少 vector 在动态扩展容量时的扩展次数

函数原型:

reserve(int len); 容器预留 len 个元素长度,预留位置不初始化,元素不可访问

// vector单端数组容器数据存取

#include <iostream>  // 包含标准输入输出流头文件
using namespace std;  // 使用标准命名空间

#include <vector>  // 使用vector单端数组容器,需包含头文件vector

void Fun_Print(vector<int>& v) {  // 使用引用方式&,传入vector<int>类型的形参v

	// vector<int>::iterator 拿到vector<int>这种容器的迭代器类型;每个容器都有一个专属的迭代器类型
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << " ";  // it是个迭代器类型,本是是个指针,需使用*解引用
	}
	cout << endl;
}

void test() {

	// 创建vector单端数组容器对象,并且通过模板参数指定容器中存放的数据的类型
	vector<int> v;

	// 利用reserve()预留空间
	v.reserve(100000);  // 如果一开始就预留足够的空间,就不用连续开辟(动态扩展)30次

	int num = 0;  // 统计开辟次数
	int* p = NULL;
	for (int i = 0; i < 100000; i++) {
		v.push_back(i);
		if (p != &v[0]) {  // 如果这个指针,不等于v容器第0位位置的地址,首地址;创建v时,会先开辟一块内存空间,当大小超过容量时,会再次开辟一块新的内存空间,首地址会发生改变
			p = &v[0];  // 让指针p指向首地址;相当于跟换了一次地址
			num++;
		}
	}

	cout << "num:" << num << endl;  // num:30;动态扩展,开辟空间,将原有数据存入新空间,释放原空间,做了30次;写了预留v.reserve(100000);则只开辟一次
}

int main() {

	test();

	system("pause");  // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果

	return 0;  // 程序正常退出
}

经典案例:评委打分

经典案例:员工分组


总结

(1)、vector 的多种构造方式没有可比性,灵活使用即可;

(2)、vector 赋值方式比较简单,使用 operator=,或者 assign 都可以;

(3)、vector 判断是否为空 — empty;

(4)、vector 返回元素个数 — size;

(5)、vector 返回容器容量 — capacity;

(6)、vector 重新指定大小 — resize;

(7)、vector 尾插 — push_back;

(8)、vector 尾删 — pop_back;

(9)、vector 插入 — insert (位置迭代器);

(10)、vector 删除 — erase (位置迭代器);

(11)、vector 清空 — clear ;

(12)、除了用迭代器获取 vector 容器中元素,[ ] 和 at 也可以;

(13)、front() 返回容器第一个元素;

(14)、back() 返回容器最后一个元素;

(15)、swap() 可以使两个容器互换,可以达到实用的收缩内存效果;

(16)、如果数据量较大,可以一开始利用 reserve() 预留空间。

  • 4
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
在 C 语言中,我们不能直接将集合类型(如 C++vector)存入数组,因为 C 语言并不提供内置的动态数组类型。不过,我们可以使用指针和动态内存分配来模拟类似的功能。 下面是一个示例代码,演示了如何将 vector 中的元素存入一个动态分配的数组: ```c #include <stdio.h> #include <stdlib.h> typedef struct { int* data; // 指向动态分配的数组 int size; // 数组的大小 } Vector; void vectorInit(Vector* vec, int size) { vec->data = (int*)malloc(sizeof(int) * size); vec->size = size; } void vectorFree(Vector* vec) { free(vec->data); vec->size = 0; } int main() { // 假设我们有一个包含 5 个元素的 vector Vector vec; vectorInit(&vec,5); // 假设 vector 中的元素为 [1, 2, 3, 4, 5] vec.data[0] = 1; vec.data[1] = 2; vec.data[2] = 3; vec.data[3] = 4; vec.data[4] = 5; // 输出数组中的元素 for (int i = 0; i < vec.size; i++) { printf("%d ", vec.data[i]); } printf("\n"); // 释放动态分配的数组内存 vectorFree(&vec); return 0; } ``` 以上代码创建了一个名为 `Vector` 的结构体,其中包含一个指向动态分配数组的指针 `data` 和一个表示数组大小的整数 `size`。`vectorInit` 函数用于初始化 `Vector` 结构体,并分配指定大小的内存空间。`vectorFree` 函数用于释放动态分配的内存。 在 `main` 函数中,我们使用 `vectorInit` 初始化一个 `Vector` 对象,并手动将元素存入 `vec.data` 数组。最后,我们使用循环打印出数组中的元素。记得在程序结束前调用 `vectorFree` 释放内存。 请注意,这只是一种模拟将集合存入数组的方法,在 C 语言中并不是直接支持的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小鹿快跑~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值