欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++ vector < vector> (tcy)

程序员文章站 2022-03-23 14:57:39
...
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) const v.at(1) 读写元素 :边界检查
operator[](int pos) v[1] 读写元素 :[]不进行边界检查
const int &front()const v.front(); 读写首元素 
const int &back()const   读写尾元素 
Iterators迭代器    
begin/cbegin/rbegin/crbegin   将迭代器返回到开头 
rend/crend/end/cend   将迭代器返回到末尾 
const int *data()const int *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,]}
	*/

 

相关标签: C/C++