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,]}
*/
下一篇: mysql php怎么查询一维数组
推荐阅读
-
PHP如何使用Ds\Vector copy()函数?
-
把一个字符串数组添加到Vector方法的实现
-
浅析java中ArrayList与Vector的区别以及HashMap与Hashtable的区别
-
JAVA Vector源码解析和示例代码
-
Java中Vector与ArrayList的区别详解
-
浅析java中ArrayList与Vector的区别以及HashMap与Hashtable的区别
-
Java中Vector与ArrayList的区别详解
-
深入分析JAVA Vector和Stack的具体用法
-
Vector Magic 入门教程 教你一步步将位图转换为矢量图形
-
Vector Magic 入门教程 教你一步步将位图转换为矢量图形