C++ vector < vector> (tcy)

1.1.说明:
	1)自动实现动态内存分配与释放,不用new和delete使得内存分配与释放更加安全
		  元素是连续存储,可通过迭代器访问元素,可用指针偏移量来访问
	2)当vector对象不为const时,const_iterator对象自身可以递增或递减;
		  但是不能对迭代器指向的对象进行修改;
		  当vector对象为const时,const_iterator对象即不能递增递减,也不能对指向对象进行修改
	3)如容器为空begin()与end()返回对象相同,即指向一个非法空间
	4)可在用完vector后调用~vector()析构函数释放内存 

1.2.allocator空间配置器:
	用于实现内存的动态分配与释放。不直接使用new和delete原因是减少开销

1.3.构造函数:
	vector<int> v1;                             //声明int型向量
	vector<int> v1(8);                          //声明大小为8的int型向量
	vector<int> v1(10, -1);                     //声明大小为10且值都是-1的int型向量
	vector<int> v1{ 1, 2, 3, 4, 5 };            //声明一个int型变量并依次赋值 

	vector<int> v2(v1);                         //声明并用v1向量初始化v2向量
	vector<int> v2(v1.begin(), v2.begin() + 3); //向量v1第0-2个值初始化v2向量 

	int arr[5] = { 1, 2, 3, 4, 5 };
	vector<int> v2(arr, arr + 5);               //arr数组初始化v1向量
	vector<int> v2(&arr[1], &arr[4]);           //arr[1]-arr[4]作为v2的初始值 

	vector<vector<int>> v1;                     //声明二维数组
	vector<vector<int>> v1(4);                  //声明4行的二维数组
	vector<vector<int>> v1(4,vector<int>(5, 0));//声明4行5列的二维数组并赋值维0 

	vector<vector<vector<int>>> a;              //声明三维数组
	vector<vector<vector<int>>> a(4);           //声明三维数组,第一维度为4

1.4.函数

 

函数实例说明
构造函数  
vector<int> v;                              声明int型向量
vector<int> v(8); 声明8个int型向量
vector<int> v(8, -1); 声明8个int型向量(值初始化为-1)
vector<int> v={ 1, 2 }; =可省 声明int型向量(并依次赋值)
vector<int> v2(v);  声明v2向量(用v向量初始化)
vector<int> v2(v.begin(), v.begin() + 3);向量v第0-2个值初始化v2向量  注1
vector<int> v(arr, arr + 5);int arr[5] = { 1, 2, 3, 4, 5 };arr数组初始化v向量 
vector<int> v2(&arr[1], &arr[4]);arr[1]-arr[4]作为v的初始值
vector<vector<int>> v1;声明二维数组
vector<vector<int>> v1(M);声明M行的二维数组
vector<vector<int>> v1(M, vector<int>(N, 0));声明M*N二维数组并赋值维0
vector<vector<vector<int>>> a;声明三维数组
vector<vector<vector<int>>> a(H);声明三维数组,第一维度为H
v.~vector<int>();析构函数
operator= 
Capacity容量  
bool empty() const; 检查容器是否为空 
size_t a= v.size() const; 返回元素数 
size_t v.max_size() const; 返回最大可能的元素数 理论限制
size_t v.capacity()const; 注2 不需分配内存即可存储元素个数=size()
void v.resize(const size_t n, [Val]);注1数组重新分配:size=n,全部赋值val
void v.shrink_to_fit();使capacity缩减至size 释放未使用的内存来减少内存使用
void v.assign(size_t newSize, const int &Val);数组重新分配:size=n,全部赋值val
void v1.assign(Iter v.It_first,Iter v.It_last);【ita,itb)将迭代器之间内容赋值给v1,类似注a;
元素访问  
const int &at(const size_t Pos) constv.at(1)读写元素 :边界检查
operator[](int pos)v[1]读写元素 :[]不进行边界检查
const int &front()constv.front();读写首元素 
const int &back()const 读写尾元素 
Iterators迭代器  
begin/cbegin/rbegin/crbegin 将迭代器返回到开头 
rend/crend/end/cend 将迭代器返回到末尾 
const int *data()constint *p = v.data();返回指向内部数组指针
操作  
void push_back(int &&_Val) 元素插入尾部;
iterator insert( const_iterator pos, const T& value ); 非模板:在迭代器所指向元素前插入val
iterator insert( const_iterator pos, size_type count, const T& value ); 非模板:在迭代器所指向元素前插入n个val
iterator insert( const_iterator pos, std::initializer_list<T> ilist ); 非模板:
void insert( iter pos, InputIt first, InputIt last); 模板:在迭代器前插入[first, last)const_iter or iter
   
v.clear();清除内容 
void pop_back()删除最后一个元素 
iterator erase(iterator position);删除迭代器所指元素;返回下一个元素的迭代器
iterator erase(iterator first, iterator last);删除[first, last)元素;返回last迭代器
erase(std::vector)erase_if(std::vector)擦除所有满足特定条件的元素 
emplace()                   高于insert避免内存拷贝或移动就地构造元素 元素插入指定位置;
emplace_back()          效率高于push_back避免内存拷贝或移动末尾就位构造一个元素 元素插入尾部;
其他  
v1.swap(v2) 交换内容 
reverse(v.begin(), v.end());         反转如:n>capacity重新分配内存;否则不影响
get_allocator 返回关联的分配器 

注1:
    n<size保留前n个元素;n>size多出部分用Val填充;
    n>max_size重新分配内存,用val填充;n<max_size不发生内存分配,只改变size

注2:
    当:数组内元素比数组长度多1数组长度翻倍!
    if(v.size() - 1 == v.capacity()) v.resize(v.capacity() * 2); 

 

2.实例: 

实例1:
	#include <iostream>
	#include<assert.h>
	#include <algorithm>//集合运算
	#include <iterator>
	#include <vector>

	using namespace std;

	template<typename T>
	void print(const char *no="", vector<T> *vec=nullptr)
	{
		cout << no<<"[";
		for (auto vec : *vec)
			cout << vec << ",";
		cout << "]" << endl;
	}

	int main(){
		//******************************************************************
		//实例1.1:定义及初始化
		vector<int> vec,v1;                         //声明int型向量= []
		vector<int> v2(4);                          //声明大小为8的int型向量= [0, 0, 0, 0, ]
		vector<int> v3(2, -1);                      //声明大小为10且值都是-1的int型向量= [-1, -1, ]
		vector<int> v4{ 1, 2, 3, 4, 5 };            //声明一个int型变量并依次赋值 = [1, 2, 3, 4, 5, ]

		vector<int> v5(v4);                         //声明并用v1向量初始化v2向量 = [1, 2, 3, 4, 5, ]
		vector<int> v6(v4.begin(), v4.begin() + 3); //向量v1第0-2个值初始化v2向量 = [1, 2, 3, ]

		int arr[5] = { 1, 2, 3, 4, 5 };
		vector<int> v7(arr, arr + 5);               //arr数组初始化v1向量[1, 2, 3, 4, 5, ]
		vector<int> v8(&arr[1], &arr[4]);           //arr[1]-arr[4]作为v2的初始值 [2, 3, 4, ]

		print("1.1=", &v1);
		print("1.2=", &v2);
		print("1.3=", &v3);
		print("1.4=", &v4);
		print("1.5=", &v5);
		print("1.6=", &v6);
		print("1.7=", &v7);
		print("1.8=", &v8);
//实例1.2:赋值(assign)赋值时会先清空数组
		
		//将动态数组v1的[ita,itb)赋值给动态数组v2
		vec.assign(v4.begin(), v4.end());     //方法1:vec= [1, 2, 3, 4, 5, ]
		vec.assign(v4.begin(), v4.begin()+5); //       等效上面
		
		//vec.assign(n,p)给动态数组vec赋值n个元素p  
		vec.assign(4, 1);                     //方法2:vec= [1, 1, 1, 1, ]
		vec = v4;                             //方法3:vec = [1, 2, 3, 4, 5, ]
//实例1.3:获取数组大小:
		assert(vec.empty() != true);
		assert(vec.size() == 5);              //不可使用length函数获取长度
		assert(vec.capacity() == 5);
		cout << vec.max_size() << endl;       //4611686018427387903
//实例1.4:交换和反转(swap、reverse)
		swap(v1, v2);                         //或者v1.swap(v2),输出结果相同
		v1.swap(v2);
		
		reverse(vec.begin(), vec.end());
		reverse(vec.begin(), vec.end());

 

//实例1.5:排序(sort)包含< algorithm>
		sort(vec.begin(), vec.end());         //方法1:默认情况下升序排列     
		
		//bool Comp(const int &a1, const int &a2){return a1 > a2;}//函数
		auto Comp = [](int &a1, int &a2) {return a1 > a2; };      //lambda
		sort(vec.begin(), vec.end(), Comp);   //方法2:自定义排序方式(此为降序) 
//实例2.1:获取元素:可修改值
		vec = v4;
		int *p = vec.data();vector<int>::iterator it=vec.begin();

		assert(vec[0] == 1);                 //方法1:读写元素,不检查数组边界
		assert(vec.at(0) == 1);              //方法2:读写元素,检查数组边界
		assert(*(it + vec.size() - 1) ==5);  //方法3:读写元素
		assert(*(p + vec.size() - 1) == 5);  //方法4:读写元素
		
		assert(vec.front()==1);              //方法5:读写首元素
		assert(vec.back()==5);               //       读写尾元素
//实例2.2:添加元素(push_back、insert)
		vec.clear();                         //清除元素
		
		vec.push_back(1); vec.push_back(2);  //方法1:数组末尾添加元素vec=[1,2,]
		//vec[3] = 2;                        //       错误此时数组长度=2
		vec.insert(vec.begin()+1,12);        //方法2:在iter前插入元素vec=[1,12,2,]
		vec.insert(vec.end(), 2, -1);        //方法3:在iter前插入n个元素vec=[1,12,2,-1,-1,]
		vec.insert(vec.begin(),v4.begin(), v4.end());//vec=[1,2,3,4,5,1,12,2,-1,-1,]
		vec.insert(vec.begin(), { 10,11 });          //vec=[10,11,1,2,3,4,5,1,12,2,-1,-1,]
//实例3.1.删除元素(pop_back、erase、remove)
		vec.pop_back();                 //方法1:删除数组vec末尾的元素vec=[10,11,1,2,3,4,5,1,12,2,-1,]
		vec.erase(vec.end() - 1);       //方法2:删除数组it指向元素vec=[10,11,1,2,3,4,5,1,12,2,]
			   
		//vec.erase(vec.begin(), 2);    //该函数未定义
		//vec.erase(vec.end(), 4);      // error 

		//remove特殊:删除指定元素,末尾插入末尾元素
		remove(vec.begin(), vec.end(), 5);       //vec=[10,11,1,2,3,4,1,12,2,2,]
		
//实例4:数组访问--有下标访问、迭代器访问、指针访问及其他等方式
		
		//4.1.通过下标访问数组
		vec = v4;
		for (int i = 0; i < vec.size(); i++){cout << vec[i]<<",";}//依次输出 1 2 3 4 5
		
		//4.2.通过迭代器访问数组
		for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) 
		{cout << *it << ","; }                        //依次输出 1 2 3 4 5
		
		//4.3.通过指针访问数组
		int *ptr = vec.data();
		for (int i = 0; i < 5; i++) { cout << *ptr++ << ","; } //依次输出 1 2 3 4 5
实例2:// vector::get_allocator 不建议使用
    //allocator_type get_allocator() const;//返回vector中allocator的拷贝对象
	
	#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING

	#include <iostream>
	#include <vector>

	using namespace std;
	
	int main(){
			std::vector<int> vec;
			//unsigned int i;
		
			// allocate an array with space for 5 elements using vector's allocator:
			int *p = vec.get_allocator().allocate(5);
		
			// construct values in-place on the array:
			for (auto i = 0; i < 5; i++) vec.get_allocator().construct(&p[i], i);
		
			std::cout << "The allocated array contains:";
			for (auto i = 0; i < 5; i++) std::cout << ' ' << p[i];// 0 1 2 3 4
			std::cout << '\n';
		
			// destroy and deallocate:
			for (auto i = 0; i < 5; i++) vec.get_allocator().destroy(&p[i]);
			vec.get_allocator().deallocate(p, 5);
	}

 

实例3.1:多维数组
	#include <iostream>
	#include <vector>

	using namespace std;

	int main(){
		//改变大小(resize)配合初始化使用,随心所欲设定数组。
		int rows = 3, cols = 4, channels = 2;
		//方法1:声明2D数组
		vector<vector<int>> v1(rows, vector<int>(cols));            //声明二维数组 

		//方法2:声明2D数组
			vector<vector<int>> v2;
		v2.resize(rows, vector<int>(cols));                         //修改二维数组大小为rows*cols

		//方法3:声明2D数组
			vector<vector<int>> v(4);                           //声明4行二维数组,每行5列并赋值为-1
		for (int i = 0; i < 4; i++) {v[i].resize(5, -1);}

		for (int i = 0; i < channels; i++)                     //3D数组赋值
		{	for (int j = 0; j < rows; j++) cout << v[i][j] << ",";cout << endl;}

		//方法1://声明3D数组 channels*rows*cols
		vector<vector<vector<int>>> arr3(channels, vector<vector<int>>(rows, vector<int>(cols)));

		//方法2://声明3D数组 channels*rows*cols
		vector<vector<vector<int>>> a(channels);                       //声明三维数组:第一维度定义为channels
		for (int k = 0; k < channels; k++) { a[k].resize(rows); }         //声明三维数组:第二维度定义为rows
		for (int i = 0; i < channels; i++) {                           //声明三维数组:第三维度定义为cols并赋初值0
			for (int j = 0; j < rows; j++) { a[i][j].resize(cols, 0); }
		}

		for (int i = 0; i < channels; i++)                     //3D数组赋值
		{
			for (int j = 0; j < rows; j++) {
				for (int k = 0; k < cols; k++){	a[i][j][k] = 1000+i*100+j*10+k; cout << a[i][j][k] << ";";}
				cout << endl;
			}
			cout << endl;
		}
	}
	/*
	-1,-1,-1,
	-1,-1,-1,

	1000; 1001; 1002; 1003;
	1010; 1011; 1012; 1013;
	1020; 1021; 1022; 1023;

	1100; 1101; 1102; 1103;
	1110; 1111; 1112; 1113;
	1120; 1121; 1122; 1123;
	*/
实例3.2:2,3维数组
	#include <iostream>
	#include <vector>

	using namespace std;

	void arr2D(int rows=3,int cols=4)                    //创建2D数组
	{
			vector<vector<int>> arr2(rows, vector<int>(cols));
			for (int i = 0; i < rows; i++)
				for (int j = 0, r = 0; j < cols; j++, r++)
					arr2[i][j] = 100+i*10+j;
		
			for (int i = 0; i < rows; i++)                     //显示
			{
				for (int j = 0; j < cols; j++)
					printf("arr[%d][%d]=%2d\n", i, j, arr2[i][j]);
				printf("\n");
			}
	}
	/*
	arr[0][0]=100
	arr[0][1]=101
	arr[0][2]=102
	arr[0][3]=103

	arr[1][0]=110
	arr[1][1]=111
	arr[1][2]=112
	arr[1][3]=113

	arr[2][0]=120
	arr[2][1]=121
	arr[2][2]=122
	arr[2][3]=123
	*/
void arr3D(int rows=3,int cols=4,int channels=2)//3D数组
	{	
		vector<vector<vector<int>>> arr3(channels, vector<vector<int>>(rows, vector<int>(cols)));
			for (int i = 0, r = 0; i < channels; i++)   //初始化3D数组
					for (int j = 0; j < rows; j++)
						for (int k = 0; k < cols; k++, r++)
							arr3[i][j][k] = 1000+i*100+j*10+k;
			
				for (int i = 0; i < channels; i++)       //显示
				{
					for (int j = 0; j < rows; j++)
					{
						for (int k = 0; k < cols; k++)
							printf("arr3[%d][%d][%d]=%d; ", i, j, k, arr3[i][j][k]);
						cout << endl;
					}
					cout << endl;
				}
	}
	/*
	arr3[0][0][0]=1000; arr3[0][0][1]=1001; arr3[0][0][2]=1002; arr3[0][0][3]=1003;
	arr3[0][1][0]=1010; arr3[0][1][1]=1011; arr3[0][1][2]=1012; arr3[0][1][3]=1013;
	arr3[0][2][0]=1020; arr3[0][2][1]=1021; arr3[0][2][2]=1022; arr3[0][2][3]=1023;

	arr3[1][0][0]=1100; arr3[1][0][1]=1101; arr3[1][0][2]=1102; arr3[1][0][3]=1103;
	arr3[1][1][0]=1110; arr3[1][1][1]=1111; arr3[1][1][2]=1112; arr3[1][1][3]=1113;
	arr3[1][2][0]=1120; arr3[1][2][1]=1121; arr3[1][2][2]=1122; arr3[1][2][3]=1123;
	*/
实例4:vector模板类
	#include <iostream>
	#include <vector>

	using namespace std;

	template <typename T1, class T2>
	class Array {
		private:
			T1 len;
			vector<T2> vec;
		public:
			Array() {}
			Array(T1 len);
			Array(const Array &b);
			Array(const T2*p, T1 len);                         //vector<int> val{ vector<int>(5,0) };
			void operator=(const Array &a);
			~Array() {};
			T1 get_len(void);
			void set_len(T1 len);
			void resize(const T1 len, T2 val = T2(0));//只能在声明(非定义)中定义默认参数 
			void view();
	};
template <typename T1, class T2>
	Array<T1, T2>::Array(T1 len) { this->len = len; vec.resize(len, T2(0)); }

	template <typename T1, class T2>
	Array<T1, T2>::Array(const Array &b) { len = b.len; vec = b.vec; }

	template <typename T1, class T2>
	Array<T1, T2>::Array(const T2*p, T1 len) { this->len = len; vector<T2> vec1(p, p + len); vec = vec1; }

	template <typename T1, class T2>
	void Array<T1, T2>::operator=(const Array &a) { len = a.len; vec = a.vec; }

	template <typename T1, class T2>
	T1 Array<T1, T2>::get_len(void) { return len; }

	template <typename T1, class T2>
	void Array<T1, T2>::set_len(T1 len) { this->len = len; resize(len); }

	template <typename T1, class T2>
	void Array<T1, T2>::resize(const T1 len, T2 val) { vec.resize(len, val); }//不允许使用默认参数 

	template <typename T1, class T2>
	void Array<T1, T2>::view()
	{
		cout << "{\"len\":" << vec.size() << ",\"vec\":[";
		for (T1 i = 0; i < vec.size(); i++) cout << vec.at(i) << ",";
		cout << "]}" << endl;
	}
class ARRAY {
		private:
			size_t len;
			vector<float> vec;
		public:
			ARRAY() {}
			ARRAY(size_t len);
			ARRAY(const ARRAY &b);
			ARRAY(const float*p, size_t len);                        //vector<int> val{ vector<int>(5,0) }; 
			void operator=(const ARRAY &a);
			~ARRAY() {};
			size_t get_len(void);
			void set_len(size_t len);
			void resize(const size_t len, float val = float(0)); //只能在声明(非定义)中定义默认参数
			void view();
	};

 

    ARRAY::ARRAY(size_t len) { this->len = len; vec.resize(len, float(0)); }
	ARRAY::ARRAY(const ARRAY &b) { len = b.len; vec = b.vec; }
	ARRAY::ARRAY(const float*p, size_t len) { this->len = len; vector<float> vec1(p, p + len); vec = vec1; }

	void ARRAY::operator=(const ARRAY &a) { len = a.len; vec = a.vec; }
	size_t ARRAY::get_len(void) { return len; }
	void ARRAY::set_len(size_t len) { this->len = len; resize(len); }
	void ARRAY::resize(const size_t len, float val) { vec.resize(len, val); }//不允许使用默认参数

	void ARRAY::view()
	{
		cout << "{\"len\":" << vec.size() << ",\"vec\":[";
		for (size_t i = 0; i < vec.size(); i++) cout << vec.at(i) << ",";
		cout << "]}" << endl;
	}
int main() {
		//测试类 
		float arr[] = {1,2,3,4};
		Array<size_t, float> a1, a2(4), a3(a2), a4(arr, 4);
		a1.view(); a2.view(); a3.view(); a4.view();
		a1 = a4; a2 = a4; a3 = a4;
		a1.view(); a2.view(); a3.view(); a4.view();
		a4.resize(6);
		a4.view();
		return 0;
	}
	/*
	{"len":0,"vec":[]}
	{"len":4,"vec":[0,0,0,0,]}
	{"len":4,"vec":[0,0,0,0,]}
	{"len":4,"vec":[1,2,3,4,]}
	{"len":4,"vec":[1,2,3,4,]}
	{"len":4,"vec":[1,2,3,4,]}
	{"len":4,"vec":[1,2,3,4,]}
	{"len":4,"vec":[1,2,3,4,]}
	{"len":6,"vec":[1,2,3,4,0,0,]}
	*/

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值