c++~第12课-----STL---array与vector

目录

STL概念

Array(定长数组) 

vector(动态数组)

array与vector嵌套


STL概念

  • STL(Standard Template Library,标准模板库)
  • STL从广义上分为:容器(container)算法(algorithm) 迭代器(iterator)
  • 容器和算法之间通过迭代器进行无缝连接。
  • STL 几乎所有的代码都采用了模板类或者模板函数

STL六大组件
STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器
1.容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据。
2. 算法:各种常用的算法,如sort、find、copy、for_each等
3. 迭代器:扮演了容器与算法之间的胶合剂。
4. 仿函数:行为类似函数,可作为算法的某种策略。
5. 适配器:一种用来修饰容器或者仿函数或迭代器接口的东西。
6. 空间配置器:负责空间的配置与管理。

容器:置物之所也
常用的数据结构:数组,链表,树,栈,队列,集合,映射表等
这些容器分为序列式容器关联式容器两种:
序列式容器:强调值的排序,序列式容器中的每个元素均有固定的位置。
关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系

算法:问题之解法也

算法分为质变算法非质变算法

质变算法:是指运算过程中会更改区间内的元素的内容,例如拷贝,替换,删除等。

非质变算法:是指运算过程中不会更改区间内的元素的内容,例如查找,计数,遍历,寻找极值等。

迭代器:容器和算法之间的胶合剂

提供一种方法,便之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式。

每个容器都有自己专属的迭代器

迭代器使用非常类似于指针,初学阶段我们可以先理解迭代器为指针

Array(定长数组) 

头文件:<array>

array里面大概是这样:

template<class T,size_t size>
class MyArray
{
public:
	MyArray()
	{
		memory = new T[size];
	}
    ~MyArray()
    {
        delete[] memory;
    }

protected:
	T* memory;
public:
    T* begin()
{
    return memory+0;//第一个元素
}
    T* end()
{
    return memory+size;//最后一个位置
}
    //类中类
    //类的对象模仿指针的行为
    class iterator
    {
        public:
            iterator(T* pMove=nullptr):pMove(pMove){}
            void operator=(T* pMove)//重载=
            {
                this->pMove=pMove;
            }
             bool operator!=(T* pMove)//重载!=
            {
               return this->pMove!=pMove;
            }
            iterator operator++(int)//重载++
            {
                this->pMove++;
                return *this
            }
            T operator*()//重载*
            {
                return pMove[0];
            }
        protected:
            T* pMove;
    }
};

void test()
{
	MyArray<int, 3>arr1;
    for(int i=0;i<3;i++)
{
    arr1[i]=i;
}
    MyArray<int,3>::iterator iter;
    for(iter=arr1.begin();iter!=arr1.end();iter++)
{
    cout<<*iter;
}
cout<<endl;   
}

array用法:

void testArray() 
{
	//存储数据的类型是:int  
//数组长度:3
//用模板的时候用的都是对象,而不是new一个对象
	array<int, 3> array1D;
	array<string, 3>* p = new array<string, 3>;
	delete p;
#define MAX 5
	array<double, 5> dAarray1D;
	//创建并初始化
	array<int, 3>  num = { 1,2,3 };
	for (int i = 0; i < array1D.size(); i++) 
	{
		array1D[i] = i;
	}
	//迭代器
}

void testExOperator() 
{
	//使用: 和数组一样的用法
	//一些函数
	array<int, 3> test = { 1,2,3 };
	cout << test.empty() << endl;
	cout << test.size() << endl;
	test.fill(5);		//填充所有的元素 ,填充为5
	for (int v : test)		
	{
		cout << v << "\t";
	}
	cout << endl;
	//交换  长度一定是要一样常
	array<int, 3> test1 = { 0,0,0};
	test.swap(test1);
	int cData[3] = { 1,2,3 };   //映射:一种对应关系,数组下标对应元素
	for (auto v : cData) 
	{
		cout << v << "\t";
	}
	cout << endl;
}
//定长数组处理自定义类型的数据
class MM
{
public:
	MM() {}
	MM(string name, int age) :name(name), age(age) {}
	void print() 
	{
		cout << name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};
void testUserData() 
{
	array<MM, 3> mmData;	//	MM array[3];
	for (int i = 0; i < mmData.size(); i++) 
	{
		string name = "name";
		mmData[i] = MM(name + to_string(i), 16 + i);
	}

	for (auto v : mmData) 
	{
		//v:就是MM的对象
		v.print();
		//cout<<v;			//想要这样输出,重载<<运算符
	}
	//迭代器访问
	//对象模仿指针,*迭代器 就是取值运算
	array<MM, 3>::iterator iter;
	//begin()
	//end(): 最后一个位置,不是最后元素的位置
	(*mmData.begin()).print();
	//(*mmData.end()).print();  越界访问
	(*(mmData.end() - 1)).print();
	for (iter = mmData.begin(); iter != mmData.end(); iter++) 
	{
		//(*iter).print();
		iter->print();
		//cout<<*iter;		//重载<<
	}
}

array当做函数参数,返回值

//array当做函数参数,返回值都可以
array<int, 3>&  returnArray(array<int, 3>& temp) 
{
	for (int i = 0; i < temp.size(); i++)
	{
		temp[i] = i;
	}
	return temp;
}

vector(动态数组)

头文件:<vector>

//辅助函数:遍历容器
template <class _Ty>
void printVector(vector<_Ty>& temp) 
{
	for (auto v : temp) 
	{
		cout << v << "\t ";
	}
	cout << endl;
}

//配合for_each使用
void pri(string val)
{
	cout << val << " ";
}

//基本用法
void test1()
{
	//模板类型:存储数据类型
	//1.不带长度的创建方式
	vector<int> vData;
	//只能用成员函数做插入
	for (int i = 0; i < 4; i++)
	{
		vData.push_back(i);//尾插法
	}
	print(vData);
	/*打印结果:0 1 2 3*/

	//2.带长度
	vector<string> strData(3);//当前动态数组长度为3
	//确定长度,可以直接使用数组法插入
	for (int i = 0; i < strData.size(); i++)
	{
		string name = "name";
		strData[i] = name + to_string(i);
	}
	print(strData);
	/*打印结果:name0 name1 name2*/
	//超过的必须用成员函数插入
	//strData[3] = "name3";//中断: vector subscript out of range(超出下标范围)
	strData.push_back("name3");//做了自动扩增
	print(strData);
	/*打印结果:name0 name1 name2 name3*/

	//3.带初始化
	vector<double> dData = { 11.1, 2.2, 3.3, 4.3, 5.4, 6.55 };//自动算出长度为6
	print(dData);
	/*打印结果:11.1  2.2  3.3  4.3  5.4  6.55*/

	//猜谜
	vector<int> iData(3);
	iData.push_back(123);//在原有内存的后面扩增,原来的数据还在
	print(iData);
	/*打印结果:0 0 0 123*/

	//1.迭代器遍历
	vector<string>::iterator iter;
	
	for (iter = strData.begin(); iter != strData.end(); iter++)
	{
		cout << *iter<<" ";
	}
	cout << endl;
	/*打印结果:name0 name1 name2 name3*/

	//2.迭代器遍历
	vector<string>::iterator isBegin = strData.begin();
	vector<string>::iterator isEnd = strData.end();
	while (isBegin != isEnd)
	{
		cout << *isBegin<<" ";
		isBegin++;
	}
	cout << endl;
	/*打印结果:name0 name1 name2 name3*/

	//3.利用STL提供遍历算法
	for_each(strData.begin(), strData.end(), pri);
	cout << endl;
	/*打印结果:name0 name1 name2 name3*/

}
//自定义类型数据
class MM 
{
public:
	MM(string name, int age) :name(name), age(age) {}
	friend ostream& operator<<(ostream& out, const MM& temp) 
	{
		out << temp.name << "\t" << temp.age;
		return out;
	}
protected:
	string name;
	int age;
};
void testUserData() 
{
	vector<MM> mmData;
	for (int i = 0; i < 3; i++) 
	{
		string name = "name";
		mmData.push_back(MM(name + to_string(i), 18 + i));
	}
	//二进制“<<”: 没有找到接受“MM”类型的右操作数的运算符(或没有可接受的转换)
	printVector(mmData);
}

void Other()
{
	vector<int> iData2 = { 1,2,3,4,5 };
	vector<int> iData3 = { 5,4,3,2,1 };
	cout<<iData2.size() << endl;//当前元素个数
	cout<<iData2.empty() << endl;//是否为nullptr
	cout << iData2.front() << endl;//访问第一个元素
	cout << iData2.back() << endl;//访问最后一个元素
	cout << iData2.at(3)<< endl;//下标访问
	cout << iData2[3] << endl;//等效于上面
	iData2.swap(iData3);//交换两个数组元素
	print(iData2);//打印结果:5 4 3 2 1
	vector<int>::iterator iter;
	cout << (*iData2.begin())<<endl;//访问第一个元素
	cout << (*(iData2.end() - 1)) << endl;//访问最后一个元素
	//修改某个元素
	iData2.emplace(iData2.begin() + 1, 999);
	print(iData2);
	iData2.emplace_back(888);//和push_back一样的功能,尾插扩增
	print(iData2);
	//iData2.emplace_front(777);//错误;不存在这种修改第一个元素的函数
	
	//删除函数,数组容器没有
	//iData2.erase(iData2.begin()+2);//数组只有伪删除,没有删除操作

	//批量复制
	int arr[] = {6,66,666};
	vector<int> cData;
	cData.assign(arr,arr+3);
	print(cData);//打印结果:6 66 666
}

array与vector嵌套

  • array与array嵌套

等效创建一个二维数组 int array[4][3],array里面存的还是array.

存的是这样的数据类型array<int, 3>,有4个一样的

void testArrayVsArray() 
{
	array<array<int, 3>, 4> arrData;  //int arrData[4][3]
	for (int i = 0; i < 4; i++) 
	{
		for (int j = 0; j < 3; j++) 
		{
			arrData[i][j] = i * j;
			cout << arrData[i][j] << "\t";
		}
		cout << endl;
	}
}
  • vector与vector嵌套

也是一个二维数组,只能创建没有带长度的

vector数组可以出现行、列数不等的情况

void testVectorVsVector() 
{
	srand((unsigned int)time(nullptr));
	vector<vector<int>> vecData;
	//一般vecotor 采用的是push_back插入
	for (int i = 0; i < 4; i++) 
	{
		vector<int> temp;
		//rand()%3 [0,2]  [2,4]
		for (int j = 0; j < rand()%3+2; j++) 
		{
			temp.push_back(i * j);
		}
		vecData.push_back(temp);
	}
    //打印
	//不等列,有可能每一列元素个数不同所以用.size()
	//不等列数的二位数组
	for (int i = 0; i < vecData.size(); i++) 
	{
		for (int j = 0; j < vecData[i].size(); j++) 
		{
			cout << vecData[i][j] << "\t";
		}
		cout << endl;
	}
}

另一种写法:

void test()
{
	vector<vector<int>> v1;
	vector<int> p1;
	vector<int> p2;
	vector<int> p3;
	vector<int> p4;
	//插入元素
	for (int i = 0; i < 4; i++)
	{
		p1.push_back(i+1);
		p2.push_back(i+2);
		p3.push_back(i+3);
		p4.push_back(i+4);
	}
	v1.push_back(p1);
	v1.push_back(p2);
	v1.push_back(p3);
	v1.push_back(p4);

		//通过大容器遍历一遍
	for (vector<vector<int>>::iterator is = v1.begin(); is != v1.end(); is++)
	{
        //(*is)-----vector<int>
		for (vector<int>::iterator vis = (*is).begin(); vis != (*is).end(); vis++)
		{
			cout << *vis << " ";
		}
		cout << endl;
	}
}

  • array嵌套vector
void testArrayVsVector()
{
	array<vector<int>, 3> vecArr;
	vector<int> vec1[3] = { { 1,2,3 } , {1,2,3,4}, {1,2}};
	for (int i = 0; i < vecArr.size(); i++) 
	{
		vecArr[i] = vec1[i];
	}
	//不等列数的二位数组
	for (int i = 0; i < vecArr.size(); i++)
	{
		for (int j = 0; j < vecArr[i].size(); j++)
		{
			cout << vecArr[i][j] << "\t";
		}
		cout << endl;
	}
	vector<array<array<vector<int>, 3>, 3>> vec;
	//慢慢剥洋葱即可
	array<array<vector<int>, 3>, 3> test;
	for (int i = 0; i < 3; i++) 
	{
		test[i] = vecArr;		//vecArr: array<vector<int>, 3>
	}
	vec.push_back(test);
	//从里到外一层层准备,最后插入到最外那层
	vector<array<array<vector<int>, 3>, 3>> test;
	//上面一行 等效下面两行
	using Data = array<array<vector<int>, 3>, 3>;
	vector<Data> test2;

	array<array<vector<int>, 3>, 3> test3;
	//上面一行 等效下面两行
	using Data2 = array<vector<int>, 3>;
	array<Data2, 3>  test3;
}
  • vector嵌套array
void testVectorVsArray() 
{
	vector<array<int, 3>> arrVec;
	array<int, 3>  arr[3] = { { 1,2,3 } , {1,2,3}, {1,2,3}};
	for (int i = 0; i < 3; i++) 
	{
		arrVec.push_back(arr[i]);
	}
	for (int i = 0; i < arrVec.size(); i++)
	{
		for (int j = 0; j < arrVec[i].size(); j++)
		{
			cout << arrVec[i][j] << "\t";
		}
		cout << endl;
	}
}

本文借鉴于c++ STL容器 array与vector嵌套_考拉爱睡觉鸭~的博客-CSDN博客_c++ 嵌套array

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Luckys-Yang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值