【C++提高编程-04】----C++之Vector容器实战

news2024/9/20 8:03:08

34889d2e7fec4a02bb0ae3a22b011a2a.png

🎩 欢迎来到技术探索的奇幻世界👨‍💻

📜 个人主页:@一伦明悦-CSDN博客

✍🏻 作者简介: C++软件开发、Python机器学习爱好者

🗣️ 互动与支持💬评论      👍🏻点赞      📂收藏     👀关注+

如果文章有所帮助,欢迎留下您宝贵的评论,

点赞加收藏支持我,点击关注,一起进步!

目录

前言

正文

01-Vector容器简介

 02-Vector容器构造函数简介

03-Vector容器赋值操作

04-Vector容器容量和大小

05-Vector容器插入和删除

06-Vector容器数据存取

07-Vector互换容器

总结


前言

       vector是C++中非常常用的容器,提供了动态数组的灵活性和高效的随机访问能力,是处理动态数据集合的重要工具之一。在使用时需要注意选择合适的数据结构来满足需求,并考虑到vector的性能特征。

正文

01-Vector容器简介

     vector是C++标准模板库(STL)中的一个容器,它提供了动态数组的功能,允许在数组的尾部高效地插入或删除元素。下面是关于vector容器的详细分析和介绍:

  1. 特点

    • vector是一个动态数组,可以根据需要自动调整大小。
    • 支持随机访问,可以通过索引快速访问元素。
    • 在尾部插入或删除元素的开销低,但在中间或头部插入或删除元素开销较大。
    • 内部基于数组实现,内存是连续存储的,因此支持高效的随机访问。
  2. 创建vector

    • 可以通过std::vector<T> v;来创建一个空的vector,其中T是存储的元素类型。
    • 也可以通过初始化列表初始化vector,比如std::vector<int> v = {1, 2, 3};
  3. 常用操作

    • push_back(element):在vector的尾部插入一个元素。
    • pop_back():删除vector的尾部元素。
    • size():返回vector中的元素个数。
    • empty():判断vector是否为空。
    • at(index):访问指定索引位置的元素。
    • back():返回最后一个元素的引用。
    • front():返回第一个元素的引用。
    • clear():清空vector中的所有元素。
  4. 遍历vector

    • 可以使用迭代器或范围循环遍历vector中的元素。
    • 例如:
      std::vector<int> v = {1, 2, 3, 4};
      for (int i : v) {
          std::cout << i << " ";
      }
    • 性能分析

      • vector在尾部插入和删除元素的时间复杂度是O(1)。
      • 随机访问的时间复杂度是O(1)。
      • 在中间或头部插入或删除元素,需要移动后续元素,时间复杂度为O(n)。
    • 注意事项

      • vector的大小超过预分配的内存时,会重新分配更大的内存,这可能导致性能开销。
      • 插入或删除操作会导致重新分配内存和元素的移动,需要注意性能消耗。

 02-Vector容器构造函数简介

    在 C++ 的标准模板库(STL)中,不同类型的容器(如 vector、map、set 等)都有各自的构造函数,用于创建容器对象并进行初始化。下面简要介绍一些常见容器的构造函数:

  vector<T> v;:构造一个空的 vector,存储类型为 T。

  vector<T> v(n);:构造一个包含 n 个元素的 vector,每个元素值为类型 T 的默认值。  

  vector<T> v(n, value);:构造一个包含 n 个元素的 vector,并每个元素初始化为 value。

  vector<T> v(begin, end);:使用迭代器指定的范围内的元素来构造 vector

        下面给出具体代码分析应用过程:这段代码主要演示了使用不同方式构造vector容器并进行操作,代码分析如下:

  1. 头文件包含

    • #include<iostream>:包含 C++ 标准输入输出流头文件。
    • using namespace std;:使用 std 命名空间,避免在后续代码中需要写出 std::前缀。
    • #include <vector>:包含 C++ STL 中的 vector 容器头文件。
  2. 函数定义

    • void printVector(vector<int> & v):定义了一个用于输出 vector<int> 容器元素的函数,并使用引用方式传入容器,以便在函数内部可以修改容器的内容。
  3. 主测试函数 test01

    • 创建一个空的 vector<int> 容器 v1,并通过 push_back 方法向容器中添加元素。
    • 调用 printVector 函数输出 v1 容器的内容。
    • 使用区间构造方法,将 v1 的元素复制到 v2 容器中,并输出 v2 内容。
    • 使用 n 个元素相同的方式构造 v3 容器,其中包含 10 个值为 100 的元素,并输出 v3 内容。
    • 使用拷贝构造方式,将 v1 容器的内容拷贝构造到 v4 容器中,并输出 v4 内容。
  4. main 函数

    • 在 main 函数中调用 test01 函数以执行测试。
    • 使用 system("pause"); 使程序暂停,防止窗口一闪而过。

       总体来说,这段代码展示了如何使用不同构造方式初始化vector容器,并演示了如何输出容器中的元素。通过对不同构造方式的使用和输出结果的比较,可以更好地理解vector容器的构造函数及其作用。

#include<iostream>
using namespace std;
#include <vector>

// 容器构造函数 

void printVector(vector<int> & v)   // 这里既然需要输出容器,必然要传入一个定义的容器变量,采用引用方式
{
	for (vector<int>::iterator it = v.begin(); it != v.end();it++)
	{
		cout << *it << " ";
	}
	cout << endl;

}

void test01()
{
	vector<int>v1;   // 1、默认构造函数 

	for (int i = 0; i < 10;i++)
	{
		v1.push_back(i);
	}

	// 调用一个输出容器的函数
	printVector(v1);   // 这里函数以引用方式做传入的参数,并且参数类型是vector<int>容器类型

	// 2、通过区间方式进行构造
	vector<int> v2(v1.begin(), v1.end());
	printVector(v2);

	// 3、n个elem方式构造
	vector<int>v3(10, 100);   // 指的是10个100
	printVector(v3);

	// 4、拷贝构造
	vector<int>v4(v1);   // 直接传入就是拷贝构造
	printVector(v4);


}

int main() {

	test01();


	system("pause");
	return 0;
}

       实例结果如下图所示:  

ffcade4743614f448929a2a7253003f3.png

03-Vector容器赋值操作

    vector容器的赋值操作可以通过多种方式进行,下面是对这些方式的详细简介:

  1. 赋值运算符 =

    • 可以使用 = 运算符将一个 vector 容器的内容赋值给另一个 vector 容器。
    • 例如:vector<int> v1 = {1, 2, 3}; vector<int> v2 = v1; 将 v1 的内容赋值给 v2
  2. assign 函数

    • assign 函数用于将指定范围内的元素赋值给 vector 容器。
    • 格式为 v.assign(first, last),其中 first 和 last 是迭代器,指定了赋值范围。
    • 例如:vector<int> v; v.assign({4, 5, 6}); 将 {4, 5, 6} 赋值给 v
  3. fill 函数

    • fill 函数用于将容器中的所有元素替换为指定值。
    • 格式为 v.fill(value),其中 value 是要填充的值。
    • 例如:vector<int> v(5); v.fill(10); 将 v 中的所有元素都填充为 10
  4. swap 函数

    • swap 函数用于交换两个 vector 容器的内容。
    • 格式为 v1.swap(v2),其中 v1 和 v2 是要交换内容的两个容器。
    • 例如:vector<int> v1 = {1, 2, 3}; vector<int> v2 = {4, 5, 6}; v1.swap(v2); 将 v1 和 v2 的内容进行交换。

       这些赋值操作提供了灵活的方式来修改 vector 容器的内容,可以根据具体需求选择适合的方式进行赋值操作。

       下面给出具体代码分析应用过程:这段代码演示了使用赋值操作符 = 和 assign 函数对vector容器进行赋值操作,下面是对代码的简要分析:

  1. 头文件包含

    • 包含了 <iostream> 头文件用于输入输出操作。
    • 使用了 using namespace std; 声明,避免了在后续代码中需要加上 std:: 命名空间前缀。
    • 引入了 <vector> 头文件,以使用vector容器。
  2. 函数定义

    • 定义了一个名为 printVector 的函数,用来输出 vector<int> 容器中的元素。
  3. 测试函数 test01

    • 创建一个空的 vector<int> 容器 v1,并通过 push_back 方法向容器中添加元素。
    • 使用printVector函数输出 v1 容器的内容。
    • 使用赋值操作符 = 将 v1 的内容赋值给另一个空的 vector<int> 容器 v2,并输出 v2 的内容。
    • 使用 assign 函数将 v1 的内容复制给另一个空的 vector<int> 容器 v3,并输出 v3 的内容。
    • 使用 assign 函数将 10 个值为 100 的元素赋值给另一个空的 vector<int> 容器 v4,并输出 v4 的内容。
  4. main 函数

    • 在 main 函数中调用 test01 函数以执行测试。
    • 使用 system("pause"); 使程序暂停,防止窗口一闪而过。

       总体来说,这段代码演示了如何使用赋值操作符 = 和 assign 函数来对vector容器进行赋值操作。通过不同的赋值方式,可以将一个容器的内容复制给另一个容器,或者将指定范围或固定值赋给容器,从而灵活地操作容器的内容。

#include<iostream>
using namespace std;
#include <vector>



// 容器赋值操作 

void printVector(vector<int> & v)   // 这里既然需要输出容器,必然要传入一个定义的容器变量,采用引用方式
{
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

}

void test01()
{
	vector<int>v1;   // 1、默认构造函数 

	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}

	// 调用一个输出容器的函数
	printVector(v1);   // 这里函数以引用方式做传入的参数,并且参数类型是vector<int>容器类型

	// 赋值操作 operator=
	vector<int>v2;
	v2 = v1;
	printVector(v2);
	// assign 赋值   区间使用,assign([a,b));
	vector<int>v3;
	v3.assign(v1.begin(), v1.end());   //v1.begin(), v1.end()
	printVector(v3);

	// assign 赋值   区间使用,assign([a,b));
	vector<int>v4;
	v4.assign(10, 100);   //赋值,和构造有区别
	printVector(v4);



}

int main() {

	test01();

	system("pause");
	return 0;
}

       实例结果如下图所示:  

34028933f30d4ec598c36203fea65b61.png

04-Vector容器容量和大小

      在 C++ STL 中,vector 容器的容量(capacity)和大小(size)是两个重要的概念,它们表示了容器中元素的数量和存储空间的分配情况。下面是关于 vector 容器容量和大小的详细介绍:

  1. 大小(size)

    • 容器的大小是指容器中当前实际存储的元素数量。
    • 可以通过 size() 成员函数获取容器的大小。
    • 当我们向容器中添加元素时,大小会增加;当我们从容器中删除元素时,大小会减少。
    • 例如,如果一个 vector 容器中有 5 个元素,则其大小为 5。
  2. 容量(capacity)

    • 容器的容量是指在不分配新的存储空间的情况下,容器可以容纳的元素数量。
    • 可以通过 capacity() 成员函数获取容器的容量。
    • 容器的容量总是大于或等于其大小。当容器的元素数量接近容量时,可能需要重新分配内存空间,以增加容器的容量。
    • 容器的容量通常会随着元素的动态添加而增加,并可能会超过实际存储的元素数量。
  3. 空间操作细节

    • 当容器的大小超过容量时,容器会自动分配更大的存储空间,并将原有元素拷贝到新的存储空间中。
    • 这种情况下,容器的容量会增加,但元素本身的数量没有改变。
    • 当容器的大小小于等于容量时,并不会释放多余的存储空间。但可以使用 shrink_to_fit() 函数来要求容器释放多余的存储空间,使容量等于大小。

       总之,vector 容器的大小和容量是在动态管理元素存储空间时非常重要的概念,了解它们能够帮助我们更好地理解容器内部的存储机制,并合理地使用容器的操作函数。

       下面给出具体代码分析应用过程:这段代码展示了容器构造函数的使用以及容器的基本操作,以下是简要的代码分析:

  1. 头文件包含

    • 代码包含了 <iostream> 头文件用于输入输出操作。
    • 使用了 using namespace std; 声明,以便在代码中直接使用 cout 和 endl 等标准库中的元素。
    • 引入了 <vector> 头文件,以使用 vector 容器。
  2. 函数定义

    • 定义了一个名为 printVector 的函数,用于输出 vector<int> 容器中的元素。
  3. 测试函数 test01

    • 创建一个空的 vector<int> 容器 v1,并通过循环将 0 到 9 的整数依次添加到容器中。
    • 调用 printVector 函数输出 v1 容器的内容。
    • 使用 empty() 函数检查容器是否为空,如果为空则输出 “v1为空”,否则输出容器的容量和大小,以及继续执行后续语句。
    • 调用 resize(15) 函数重新指定容器 v1 的大小为 15,这会导致容器的容量自动扩大,由于原先只有 10 个元素,额外的 5 个位置会用默认值(0)填充。
    • 再次调用 printVector 函数输出修改后的 v1 容器的内容,并输出当前容器的容量。
  4. main 函数

    • 在 main 函数中调用 test01 函数以执行测试。
    • 使用 system("pause"); 使程序暂停,防止窗口一闪而过。

       总体来说,这段代码展示了使用 vector 容器的构造函数、基本操作(如输出容器内容、检查容器是否为空、获取容器的容量和大小,重新指定容器大小等)。通过这些操作,我们可以更好地理解 vector 容器的特性和使用方法。

#include<iostream>
using namespace std;
#include <vector>



// 容器构造函数 

void printVector(vector<int> & v)   // 这里既然需要输出容器,必然要传入一个定义的容器变量,采用引用方式
{
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

}

void test01()
{
	vector<int>v1;   // 1、默认构造函数 

	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}

	// 调用一个输出容器的函数
	printVector(v1);   // 这里函数以引用方式做传入的参数,并且参数类型是vector<int>容器类型

    if (v1.empty())   // 为真,代表容器为空
    {
		cout << "v1为空" << endl;
    }
	else
	{
		cout << "v1不为空" << endl;
		cout << "v1的容量" << v1.capacity() << endl;   // 容量一定大于等于插入的参数个数
		cout << "v1的大小" << v1.size() << endl;

	}

	// 重新指定容器大小
	v1.resize(15);
	printVector(v1);// 这里重新指定了size大小,容器容量回自动扩大,由于v1本来只有10个数值,另外5个参数默认为0
	cout << "v1此时的容量" << v1.capacity() << endl;



}

int main() {

	test01();


	system("pause");
	return 0;
}

       实例结果如下图所示:  

8bf213845ade4d3bafabb01c274710bf.png

05-Vector容器插入和删除

    在 C++ STL 中,vector 容器提供了丰富的方法用于插入和删除元素,下面是关于 vector 容器插入和删除操作的详细介绍:

插入操作:

  1. push_back 在容器的末尾插入一个元素。

    vector<int> v = {1, 2, 3};
    v.push_back(4); // 将元素 4 插入到容器末尾后,容器变为 {1, 2, 3, 4}
    
  2. insert 在指定位置插入元素或一段元素。

    vector<int> v = {1, 2, 3, 4, 5};
    v.insert(v.begin() + 2, 10); // 在第三个位置(索引为2)插入元素 10,容器变为 {1, 2, 10, 3, 4, 5}
    v.insert(v.begin() + 3, {20, 30, 40}); // 在第四个位置插入元素 20, 30, 40,容器变为 {1, 2, 10, 20, 30, 40, 3, 4, 5}
    

删除操作:

  1. pop_back 删除容器末尾的元素。

    vector<int> v = {1, 2, 3, 4, 5};
    v.pop_back(); // 删除容器末尾的元素,容器变为 {1, 2, 3, 4}
    
  2. erase 删除指定位置或指定范围内的元素。

    vector<int> v = {1, 2, 3, 4, 5};
    v.erase(v.begin() + 2); // 删除第三个位置的元素,容器变为 {1, 2, 4, 5}
    v.erase(v.begin() + 1, v.begin() + 4); // 删除从第二个位置至第四个位置的元素,容器变为 {1, 5}
    
  3. clear 清空容器中的所有元素,使容器为空。

    vector<int> v = {1, 2, 3, 4, 5};
    v.clear(); // 清空容器中的所有元素,容器变为空
    
  4. 注意事项:

    • 插入和删除元素可能会导致迭代器失效,要特别注意在循环中插入或删除元素时的迭代器处理。
    • 删除元素后,后续的元素会向前移动,因此要注意索引的变化。

       通过上述详细介绍,你可以深入了解 vector 容器在实际编程中如何进行元素的插入和删除操作,合理地利用这些操作可以使代码更加灵活和高效。

       下面给出具体代码分析应用过程:  这段代码主要演示了关于 vector 容器的插入和删除操作,以下是代码的简要分析:

  1. 头文件包含和函数定义

    • 引入了 <iostream> 和 <vector> 头文件,用于输入输出以及使用 vector 容器。
    • 定义了一个用于输出 vector<int> 容器元素的函数 printVector
  2. test01 函数

    • 创建一个空的 vector<int> 容器 v1
    • 使用 push_back 方法向容器尾部依次插入元素 10, 20, 30, 40, 50。
    • 调用 printVector 函数输出容器 v1 中的所有元素。
    • 使用 pop_back 方法删除容器尾部的元素,此处删除了元素 50。
    • 使用 insert 方法在容器的起始位置插入元素 100。
    • 使用 erase 方法删除容器的第一个元素。
    • 注释掉了 v1.clear() 方法,该方法用于清空容器中的所有元素,但在此处被注释掉未执行。
  3. main 函数

    • 在 main 函数中调用 test01 函数以执行测试。
    • 使用 system("pause"); 使程序暂停,防止窗口一闪而过。
  4. 运行结果

    • 程序执行后,将依次输出 v1 容器中的元素,每次操作后的容器内容都会被打印出来。

        通过这段代码的执行,你可以了解 vector 容器的插入和删除操作的具体细节,并体会这些操作对容器中元素的影响。如果想要继续学习和探究,可以尝试更多不同方式的插入和删除操作,以加深对 vector 容器的理解。

#include<iostream>
using namespace std;
#include <vector>



/*  push_back(ele); //尾部插入元素ele
	pop_back(); //删除最后一个元素
	insert(const_iterator pos, ele); //迭代器指向位置pos插入元素ele
	insert(const_iterator pos, int count,ele); //迭代器指向位置pos插入count个元素ele
	erase(const_iterator pos); //删除迭代器指向的元素
	erase(const_iterator start, const_iterator end); //删除迭代器从start到end之间的元素
	clear(); //删除容器中所有元素
*/
void printVector(vector<int> & v)   // 这里既然需要输出容器,必然要传入一个定义的容器变量,采用引用方式
{
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

}

void test01()
{
	vector<int>v1;   // 1、默认构造函数 
	// 1、插入数据,尾插法
	v1.push_back(10);
	v1.push_back(20);
	v1.push_back(30);
	v1.push_back(40);
	v1.push_back(50);


	// 调用一个输出容器的函数
	printVector(v1);   // 这里函数以引用方式做传入的参数,并且参数类型是vector<int>容器类型
	// 2、尾删
	v1.pop_back();   // 这里直接默认删除尾部数据
	printVector(v1);

	// 3、插入
	v1.insert(v1.begin(), 100);  // 这里第一个参数必须插入一个迭代器,第二参数是需要插入的数值
	printVector(v1);

	// 4、删除
	v1.erase(v1.begin());
//	v1.clear();// 清空操作
	printVector(v1);



}

int main() {

	test01();


	system("pause");
	return 0;
}

       实例结果如下图所示:  

dac686e47eed48cdb3be6402967f14f4.png

06-Vector容器数据存取

    在 C++ 的标准模板库(STL)中,vector 容器提供了多种方法用于数据的存取,下面是关于 vector 容器数据存取操作的详细介绍:

数据存取:

  1. 使用下标 [] 运算符

    • 可以通过下标访问 vector 容器中的元素。
    vector<int> v = {10, 20, 30, 40, 50};
    cout << v[1]; // 输出第二个元素,即 20
    
  2. at 方法

    • 类似于 [] 运算符,但提供了边界检查,并在索引超出范围时抛出异常。
    vector<int> v = {10, 20, 30, 40, 50};
    cout << v.at(3); // 输出第四个元素,即 40
    
  3. 使用迭代器

    • 可以使用迭代器访问 vector 容器中的元素,包括正向迭代器和反向迭代器。
    vector<int> v = {10, 20, 30, 40, 50};
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << " ";
    }
    
  4. front 和 back 方法

    • front 方法返回容器中第一个元素的引用,back 方法返回容器中最后一个元素的引用。
    vector<int> v = {10, 20, 30, 40, 50};
    cout << v.front(); // 输出第一个元素,即 10
    cout << v.back(); // 输出最后一个元素,即 50
    
  5. data 方法

    • 返回指向存储容器内所有元素的数组的指针,常用于与 C 风格的函数进行交互。
    vector<int> v = {10, 20, 30, 40, 50};
    int *ptr = v.data();
    

       通过以上详细介绍,你可以更全面地了解如何使用 vector 容器进行数据的存取操作。合理地选择不同的方法可以方便地访问和操作 vector 容器中的元素,提高代码效率和可读性。

       下面给出具体代码分析应用过程:这段代码主要演示了使用 vector 容器存储一组整数数据,并通过不同方式进行数据的访问操作。以下是对代码的简要分析:

  1. 头文件包含和命名空间

    • 引入了 <iostream> 头文件用于输入输出,以及 <vector> 头文件用于使用 vector 容器。
    • 使用 using namespace std; 表示使用 std 命名空间。
  2. test01 函数

    • 创建一个空的 vector<int> 容器 v1
    • 使用 push_back 方法向容器中插入整数数据 0 到 9。
    • 通过 [] 运算符访问容器中的元素,依次输出所有元素。
    • 通过 at 方法访问容器中的元素,同样依次输出所有元素。
    • 在每种方式下,使用 for 循环遍历容器中的元素并输出。
  3. main 函数

    • main 函数调用 test01 函数来执行测试。
  4. 运行结果

    • 程序执行后,将会输出两次相同的整数序列,分别通过 [] 运算符和 at 方法访问 vector 容器中的元素。
  5. 补充说明

    • 通过 [] 运算符和 at 方法都可以实现对 vector 容器元素的访问,但使用 at 方法能够进行边界检查,当索引越界时会抛出异常。
    • 在这段代码中,循环遍历容器并输出元素是比较常见的操作,可以方便地查看容器中的数据内容。

       通过这段代码的简要分析,你可以更加熟悉如何在 C++ 中使用 vector 容器存储数据并进行访问操作,同时了解了如何通过 [] 运算符和 at 方法来访问容器中的元素。这些基本操作对于处理容器数据是非常重要的,希望这样的分析对你有所帮助。

#include<iostream>
using namespace std;
#include <vector>



void test01()
{
	vector<int>v1;   // 1、默认构造函数 

	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}

	// 可以使用[]方式访问
	for (int i = 0; i < v1.size();i++)
	{
		cout << v1[i] << " ";
	}
	cout << endl;

	// 使用at方式
	for (int i = 0; i < v1.size(); i++)
	{
		cout << v1.at(i) << " ";
	}
	cout << endl;




}

int main() {

	test01();


	system("pause");
	return 0;
}

        实例结果如下图所示:   b09ea5840c51417f89975e074125f9c3.png

07-Vector互换容器

    在 C++ STL 中,vector 容器提供了 swap 方法用于交换两个容器的内容,实现容器之间的互换操作。下面是关于 vector 容器互换容器内容的详细介绍:

swap 方法:

  1. swap 方法

    • swap 方法可以交换两个容器的所有元素,实现容器内容的互换操作。
    • 语法:void swap(vector& x) noexcept;,其中 x 是另一个 vector 容器。
    • 注意:交换后,原本的容器会变为空,另一个容器则包含原本容器中的所有元素。
  2. 示例代码

    vector<int> v1 = {1, 2, 3, 4};
    vector<int> v2 = {5, 6, 7};
    
    v1.swap(v2);
    
    // 现在 v1 包含 {5, 6, 7},v2 变为空
    
  3. 注意事项

    • swap 不会进行元素的复制或移动,而是直接交换指向元素的内部指针。
    • 交换操作对于大容器的性能开销较小,适合用于交换大量数据的情况。
  4. 与其他容器的互换

    • 除了两个相同类型的 vector 容器之间可以互换外,不同类型的容器也可以通过 swap 方法进行互换。
    • 例如,vector<int> 与 vector<double> 之间的互换也是可能的。

       通过使用 swap 方法,可以方便快速地交换两个 vector 容器的所有元素,而无需复制或移动元素,提高了程序的效率和性能。这对于需要频繁交换大量数据的情况特别有用,让程序更加高效。希望这个详细介绍对你有所帮助。

       下面给出具体代码分析应用过程:这段代码主要演示了使用 vector 容器的 swap 方法来交换容器内容,并展示了通过巧妙利用 swap 方法来收缩内存空间的用法。以下是对代码的简要分析:

  1. 头文件包含和命名空间

    • 引入了 <iostream> 头文件用于输入输出,以及 <vector> 头文件用于使用 vector 容器。
    • 使用 using namespace std; 表示使用 std 命名空间。
  2. printVector 函数

    • 定义了一个函数 printVector,用于打印传入的 vector 容器中的所有元素。
  3. test01 函数

    • 创建两个 vector<int> 容器 v1 和 v2,分别存储递增和递减的整数序列。
    • 打印输出两个容器的元素。
    • 使用 swap 方法交换 v1 和 v2 的内容。
    • 再次打印输出两个容器的元素,展示交换后的结果。
  4. test02 函数

    • 创建一个 vector<int> 容器 v,存储从 0 到 99999 的整数序列。
    • 打印输出容器的容量和大小。
    • 使用 resize 方法将容器大小重新指定为 3,但容量没有改变。
    • 利用 swap 方法来收缩内存空间,将匿名对象和原容器进行交换,实现收缩空间的效果。
    • 最后打印输出容器的容量和大小,展示内存空间被收缩的效果。
  5. 运行结果

    • 程序执行后,会输出各个阶段的容器内容、容量和大小信息,展示了 swap 方法交换容器内容和收缩内存空间的效果。

       通过这段代码的简要分析,你可以了解到如何使用 swap 方法来交换两个容器的内容,并学习了一种利用 swap 方法来收缩 vector 容器内存空间的技巧。这种技巧能够避免浪费过多内存空间,提高程序的效率。希望这个分析对你有所帮助。

#include<iostream>
using namespace std;
#include <vector>

void printVector(vector<int> & v)
{
	for (vector<int>::iterator it = v.begin(); it != v.end();it++)
	{
		cout << *it <<" ";
	}
	cout << endl;
}
void test01()
{
	vector<int>v1;   // 1、默认构造函数 

	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	cout << "交换前" << endl;
	printVector(v1);

	vector<int>v2;   // 1、默认构造函数 

	for (int i = 10; i > 0; i--)
	{
		v2.push_back(i);
	}
	
	printVector(v2);

	cout << "交换后" << endl;
	v1.swap(v2);
	printVector(v1);
	printVector(v2);



}


// 实际用途
// 巧用swap交换函数可以收缩内存空间
void test02()
{
	vector<int>v;
	for (int i = 0; i < 100000;i++)
	{
		v.push_back(i);
	}
	cout << "v的容量" << v.capacity() << endl;   // 138255
	cout << "v的大小" << v.size() << endl;       // 100000

	v.resize(3);   // 重新指定大小  ,容量并没有改变,很容易浪费空间
	cout << "v的容量" << v.capacity() << endl;    // 138255
	cout << "v的大小" << v.size() << endl;        // 3

	// 巧用swap交换函数可以收缩内存空间
	vector<int>(v).swap(v);    // vector<int>(v)匿名对象的内存,在执行完毕后,将被自动释放
	cout << "v的容量" << v.capacity() << endl;    // 3
	cout << "v的大小" << v.size() << endl;        // 3

}


int main() {

	test02();


	system("pause");
	return 0;
}

        实例运行结果如下图所示:

ee88d9ef24e8491589021a4f30fa4ef2.png

总结

    在 C++ STL 中,vector 容器是一个非常常用的动态数组容器,提供了灵活的数组功能。以下是关于 vector 容器的总结:

特点:

  1. 动态数组

    • vector 是一个动态数组容器,可以根据需要动态增长或缩减其大小。
  2. 连续存储

    • vector 中的元素在内存中是连续存储的,因此支持高效的随机访问。
  3. 大小可变

    • 可以通过 push_back 方法向尾部添加元素,也可以通过 pop_back 方法删除尾部元素。
  4. 下标访问

    • 可以使用下标运算符 [] 或 at 方法来访问容器中的元素。
  5. 尾部插入、删除高效

    • 在尾部插入或删除元素的时间复杂度为常数时间,即 O(1)
  6. 插入、删除中间元素效率低

    • 在中间位置插入或删除元素的时间复杂度为线性时间,即 O(n),因为需要移动元素。

常用操作:

  1. 构造与赋值

    • 支持多种构造方式,如默认构造、指定大小和初始值构造等。
    • 可以使用 assign 方法进行赋值操作。
  2. 访问元素

    • 提供了 [] 运算符、at 方法、front 和 back 方法等访问元素的方式。
  3. 插入与删除

    • 提供了 push_backpop_backinserterase 等方法用于插入和删除元素。
  4. 容量操作

    • 可以使用 size 方法获取容器中元素的数量,使用 capacity 方法获取容器的容量。
    • 支持 resize 方法调整容器的大小,以及 reserve 方法预留容量。
  5. 交换容器

    • 可以使用 swap 方法交换两个 vector 容器的内容,用于快速交换大量数据或收缩内存空间。

   vector 容器是 C++ 中常用的动态数组容器,具有灵活性和高效性。它支持动态增长和缩减、高效的尾部插入和删除操作,以及随机访问元素等功能。同时,通过 swap 方法可以方便地交换容器内容,用于优化内存使用。在 C++ 编程中,vector 是处理动态数组数据的首选容器之一。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1697259.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

初步认识栈和队列

Hello&#xff0c;everyone&#xff0c;今天小编讲解栈和队列的知识&#xff01;&#xff01;&#xff01; 1.栈 1.1栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端 称为栈顶&…

Mysql 找出未提交事务的SQL及死锁

未提交事务&#xff1a; 通过查看information_schema.INNODB_TRX视图,您可以了解当前系统中正在运行的事务情况,从而进行问题排查和性能优化。 SELECT * FROM information_schema.innodb_trx; 通过trx_state为RUNNIG,trx_started判断是否有一直RUNNING的事务。 如果有未提交…

Linux修炼之路之冯系结构,操作系统

目录 一&#xff1a;冯诺依曼体系结构 1.五大组件 2.存储器存在的意义 3.几个问题 二&#xff1a;操作系统 接下来的日子会顺顺利利&#xff0c;万事胜意&#xff0c;生活明朗-----------林辞忧 一&#xff1a;冯诺依曼体系结构 我们当代的计算机的基本构成都是由冯诺依曼…

【深度学习】第1章

概论: 机器学习是对研究问题进行模型假设,利用计算机从训练数据中学习得到模型参数,并最终对数据进行预测和分析,其基础主要是归纳和统计。 深度学习是一种实现机器学习的技术,是机器学习重要的分支。其源于人工神经网络的研究。深度学习的模型结构是一种含多隐层的神经…

MySQL增删查改进阶

数据库约束表的关系增删查改 目录 一.数据库约束类型 NOT NULL约束类型 UNIQUE 唯一约束 DEFAULT 默认值约束 PRIMARY KEY&#xff1a;主键约束 FOREIGN KEY :W外键约束 二&#xff0c;查询 count&#xff08;&#xff09;两种用法 sum&#xff0c;avg&#xff0c;max…

python文件处理之os模块和shutil模块

目录 1.os模块 os.path.exists(path)&#xff1a;文件或者目录存在与否判断 os.path.isfile(path)&#xff1a;判断是否是文件 os.path.isdir(path)&#xff1a;判断是否是文件夹 os.remove(path)&#xff1a;尝试删除文件 os.rmdir(path)&#xff1a;尝试删除目录 os.m…

【设计模式】——装饰模式(包装器模式)

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

行为型设计模式之模板模式

文章目录 概述原理结构图实现 小结 概述 模板方法模式(template method pattern)原始定义是&#xff1a;在操作中定义算法的框架&#xff0c;将一些步骤推迟到子类中。模板方法让子类在不改变算法结构的情况下重新定义算法的某些步骤。 模板方法中的算法可以理解为广义上的业…

Linux驱动(3)- LInux USB驱动层次

在Linux系统中&#xff0c;提供了主机侧和设备侧USB驱动框架。 从主机侧&#xff0c;需要编写USB驱动包括主机控制器驱动&#xff0c;设备驱动两类&#xff0c;USB 主机控制驱动程序控制插入其中的USB设备。 USB设备驱动程序控制该设备如何作为从设备与主机进行通信。 1.主机…

文件夹打开出错?这里有你需要的数据恢复与预防指南

在日常使用电脑时&#xff0c;我们有时会遇到文件夹打开出错的情况。当你尝试访问某个文件夹时&#xff0c;系统可能会弹出一个错误提示&#xff0c;告诉你无法打开该文件夹。这种情况不仅会影响我们的工作效率&#xff0c;还可能导致重要数据的丢失。接下来&#xff0c;我们将…

Flutter-自定义折叠流布局实现

需求 在 Flutter 开发中&#xff0c;常常需要实现自定义布局以满足不同的需求。本文将介绍如何通过自定义组件实现一个折叠流布局&#xff0c;该组件能够显示一系列标签&#xff0c;并且在内容超出一定行数时&#xff0c;可以展开和收起。 效果 该折叠流布局可以显示一组标签…

ROCm上运行Transformer

10.7. Transformer — 动手学深度学习 2.0.0 documentation (d2l.ai) 代码 import math import pandas as pd import torch from torch import nn from d2l import torch as d2l#save class PositionWiseFFN(nn.Module):"""基于位置的前馈网络""&qu…

【uni-best+UView】使用mitt实现自定义错误对话框

痛点 目前在设计一个uni-best的前端全局的异常提示信息&#xff0c;如果采用Toast方式&#xff0c;对微信支持的不友好。微信的7中文长度连个NPE信息都无法完整显示&#xff0c;更不用提Stacktrace的复杂报错了。如果使用对话框&#xff0c;必须在页面先预先定义&#xff0c;对…

C/C++ 进阶(2)多态

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;C 目录 一、多态的概念 二、多态的定义及其实现 1、多态的构成条件 2、虚函数 3、虚函数重写 a.常规 b.两个例外 1、协变&#xff08;基类与派生类虚函数返回值类型不同&#xff09; 2、析构函数重…

10G UDP协议栈 (9)UDP模块

目录 一、UDP协议简单介绍 二、UDP功能实现 三、仿真 一、UDP协议简单介绍 UDP协议和TCP协议同位于传输层&#xff0c;介于网络层&#xff08;IP&#xff09;和应用层之间&#xff1a;UDP数据部分为应用层报文&#xff0c;而UDP报文在IP中承载。 UDP 报文格式相对于简单&am…

单工无线发射接收系统

1 绪论 随着无线电技术的发展,通讯方式也从传统的有线通讯逐渐转向无线通讯。由于传统的有线传输系统有配线的问题,较不便利,而无线通讯具有成本廉价、建设工程周期短、适应性好、扩展性好、设备维护容易实现等特点,故未来通讯方式将向无线传输系统方向发展。同时,实现系…

leedcode【203】. 移除链表元素——Java解法

Problem: 203. 移除链表元素 题目思路解题方法复杂度Code效果 题目 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val…

【图解IO与Netty系列】IO多路复用

IO多路复用 为什么要使用IO多路复用Linux的IO多路复用接口selectpollepoll 为什么要使用IO多路复用 我们常用的IO模型是BIO&#xff0c;我们Java里的IO流大多数都是BIO&#xff0c;也就是同步阻塞式IO&#xff0c;这种IO操作的好处是简单方便&#xff0c;但是缺点也很明显——…

【技术实操】银河高级服务器操作系统实例分享,TCP长连接与短连接详细说明

1.服务器环境以及配置 物理机/虚拟机/云/容器 物理机 处理器&#xff1a; HUAWEI Kunpeng 920 具体操作系统版本 Kylin-Server-10-SP1-Release-Build20-20210518- aarch64 内核版本 kernel-4.19.90-23.8.v2101.ky10.aarch64 2.问题现象描述 对TCP长连接有疑问 1、如何…