STL容器篇之array与vector 学习篇
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中最后一个元素
如果这样操作,将会出现如下错误
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 };