STL容器篇之array与vector(学习篇)

时间:2022-10-14 01:21:32

array

简单介绍

array 是STL 中一个容器, 是一个定值数组
相当于C语言中 array[5].
在C++中, 使用容器都要使用想对应的头文件
例如:
使用array这个容器,就要使用 这个头文件

#include<vector>

创建对象以及赋值

二种方法:

第一种:array<数据类型, 大小> 对象;
赋值 : 例如:array<int , 3> = {0, 2, 4};
第二种: 用new
array<数据类型, 大小> * 变量名称 = new array<数据类型, 大小>;
赋值: (*变量名称)[数组下标] = 值
例如 : *arr3[0] = “温柔了岁月”

	//array 2种方法 创建对象
	//第一种 array<数据类型, 大小> 对象
	array<int, 3> arr1;

	//第一种直接赋初值  array<数据类型, 大小> 对象 = {0, 2}可以直接赋值
	array<int, 3> arr2 = { 0, 2 };

	//第二种:用new
	array<string, 3>* arr3 = new array<string, 3>;
  //赋值操作* arr3)[0] = "温柔了岁月";
   
   delete arr3;

通常使用第一种,第二种赋值方式相对于第一种过于麻烦

array中常用内置函数介绍

使用方法: 对象.函数

1.size(), 计算大小
2.empty(), 判断是否为空
3.begin(), 可以指向array数组的第一个元素,
注意:也可以表示array数组中的第一个元素
4.end(), 指向array数组中的最后一个元素,
注意:不表示array数组中的最后一个元素
5. front(), 第一个元素
6. back(), 最后一个元素
7. at(), 可以访问array数组中的数据**,注意需要加参数,array数组的下标**

这些内置函数, 有的后面会多次涉及最好记住

// STL中内置的函数 size() 计算大小
	cout << arr2.size() << endl;
	cout << arr3->size() << endl;

	//C++中empty ()函数的作用是用来判断容器是否为空 
	//empty ()函数返回值为true,说明容器为空 empty ()函数返回值为false,说明容器不为空

	cout << arr1.empty() << endl;

array数组的访问(正向遍历)

第一种:简单的for循环,用 cout 遍历打印不过array的大小用size计算
第二种:也是for循环,与第一种不同的是, 用array的内置函数at,来打印
第三种:则是遍历容器常用的方法
用迭代器的方法(三种)
这里讲解第一种,也是用的最多的
首先
1.array<数据类型, 大小> ::(作用域) iterator(迭代器) 对象 = arr2.begin(),指向 第一个 元素
2.array<数据类型, 大小> ::(作用域) iterator(迭代器) 对象 = arr2.end(),指向 最后一个元素
3.for循环挨个打印,直到到最后一个元素

迭代器你可以变相的理解为指针,代表着地址
所以 * arr2.begin() 代表着值

//array的访问

	//第一种 cout

	//for (int i = 0; i < arr2.size(); i++)
	//{
	//	cout << arr2[i] << endl;
	//}
	第二种 内置函数at()

	//for (int i = 0; i < arr2.size(); i++)
	//{
	//	cout << arr2.at(i) << endl;
	//}

	//运用迭代器  三种方法
	//第一种(常用)

	for (array<int, 3> ::iterator it = arr2.begin(); it != arr2.end(); it++)
	{
		cout << *it << endl;
	}
	
	 //第二种方法

	array<int, 3> ::iterator itBegin = arr2.begin();
	array<int, 3> ::iterator itEnd = arr2.end();

	while (itBegin != itEnd)
	{
		cout << *itBegin << endl;
		
		itBegin++;
	}
	//第三种 each_for()算法  ,这里暂不介绍, 后续讲算法的时候介绍

指针形式遍历

for (int i = 0; i < arr3->size(); i++)
	{
		cout << arr3->at(i) << endl;
	}

逆向遍历(反向迭代器)

正向迭代器:iterator
反向迭代器 reverse_iterator

rbegin() 指向array中最后一个元素
rend()指向array中第一个元素

	for (array<int, 3> ::reverse_iterator it = arr2.rbegin(); it != arr2.rend(); it++)
	{
		cout << *it << endl;
	}

*注意:不能用正向迭代器,反着写,逆向打印array中的元素
因为 arr2.end() 并不代表 array中最后一个元素

如果这样操作,将会出现如下错误
STL容器篇之array与vector(学习篇)

array的嵌套

array本身是一个定长的数组,
嵌套一次,便是定长的二维数组,
嵌套二次,便是定长的三位数组。

这里需要注意的是如何打印

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

int main()
{
	array<array<int, 4>, 3> date;  //表示 3X4的二维数组

	for (int i = 0; i < date.size(); i++) // date.size()表示行的大小
	{
		for (int j = 0; j < date[i].size(); j++)  // date[i].size(),表示列的大小
		{
			date[i][j] = i;     //随便赋的值
			cout << date[i][j] << " ";
		}
		cout << endl;
	}
	array<array<array<int, 4>, 4>, 4>;     //4X4X4的三维数组,可以无限嵌套

	system("pause");

	return 0;
}

victor(动态数组)

简单介绍

数组的大小是动态的,你想要多大,系统就会给你多大
当然容器, 也需要使用这个的头文件

#include<vector>

创建方式

vector的创建方式有很多

1.不带长度的创建
第一种情况:不赋初值
这种情况的创建,需要注意的是不能利用数组下标来进行操作
错误案例:

//创建方式
	//1. 不带长度的构建,
    //如果没有进行赋初值, 不能通过数组下标进行访问元素
	vector<int> name;
	name[0] = 1; //错误案例

第二种情况: 赋初值, 赋初值可以通过数组下标来操作(系统会自动给出数组的大小), 但不能越界进行操作
案例:

//错误案例
vector<int>name2 = {1, 2}; //系统自己自动给出数组大小为2
name2[3] = 1;  //越界进行操作, 程序中断

2.带长度的构建
(可以通过数组下标访问,但肯定不能越界)

//2.带长度的构建
	//创建方式:vector<数据类型> 名称(数组的大小)
	vector<int> name2(2);

	name2[0] = 1;  //正确案例, 在数组长度的范围之类
	name2[3] = 3;  //错误案例, 超出了数组的长度

3.带自动增长功能的是在成员函数中实现的
利用 push_back(尾部插入, 也就是最后面插入)

像前面几种情况, 如果越界或者无法通过数组下标来操作的话,都可以通过push_back()函数来进行插入

案例:
push_back(插入的数据);

name1.push_back(1);
name2.push_back(3)

遍历方式(这里介绍一种方便的新式for循环)

第一种:根据C++11的特性
这里有一种新式的for循环
这种新式的for循环,相对于,迭代器的方法更加的简洁,
建议使用这种,当然前面array的遍历也可以用这个,

for (auto &v: name2) //取地址
	{
		cout << v << endl; //将name2中的元素从第一个挨个打印
	}

第二种:迭代器的方法



	//迭代器的方法打印
	for (vector<int>::iterator it = name2.begin(); it != name2.end(); it++)
	{
		cout << *it << endl;
	}

逆向访问

//逆向打印
	for (vector<int> ::reverse_iterator rit = name2.rbegin(); rit != name2.rend(); rit++)
	{
		cout << *rit << endl;
	}

数组遍历的小总结

通过array和vector的遍历学习,相信你已经有所体会
遍历的方式:一般采用
1.新式的for循环
2.迭代器的方法

3.或者使用size()成员函数,挨个遍历打印

逆向遍历
反向迭代器

访问第一个元素

//1.可以通过成员函数begin()和front()
cout << name2.front() << * name2.begin();
//2.也可以通过 c成员函数at(0)
cout << name2.at(0) << endl; 
//注意不能使用rend()函数去访问,程序会中断

访问最后一个元素

1.成员函数 back()
//同样注意:注意不能使用rend()函数去访问,程序会中断
cout << name2.back();
2.反向迭代器 rbegin();
cout << *name2.rbegin()<< endl;
3.
cout << name2.at(name2.size()- 1) << endl;
4.
cout << *(name2.end() - 1) << endl;

vector的嵌套

vector本身是一个动态的数组,
嵌套一次,便是动态的二维数组,
嵌套二次,便是动态的三位数组。

这里使用了随机数的方法,实现一个不等长的二维数组
如果对随机数不太熟悉的话可以看下,当然要加头文件(这里只是部分代码)

include<time.h>
vector<vector<int>> date; //一个动态的二维数组

	srand((unsigned int)time(NULL)); //创建随机种子

	//利用随机数, 实现一个不等长的二维数组

	int len = rand() % 5 + 1;

	for (int i = 0; i < 3; i++)
	{
		vector<int> name;

		for (int j = 0; j < len; j++)
		{
			name.push_back(j);
		}
		date.push_back(name);
	}

	for (int i = 0; i < date.size(); i++)
	{
		for (int j = 0; j < date[i].size(); j++)
		{
			cout << date[i][j] << " ";
		}
		cout << endl;
	}

vector与array的相互嵌套

vector与array的相互嵌套也很简单,
弄清楚了array的嵌套和vector的嵌套
他们的相互嵌套就很好理解
只需清楚,是谁嵌套谁

	//array与vector 可以相互嵌套

	vector<array<int, 3>> arr1;
	arr1.push_back(array<int, 3>{0,4});
	

	array<vector<int>, 3> arr2;

	arr2[0] = vector<int>{ 1, 2 };