数据结构算法刷题笔记——二、2.1 vector

数据结构算法刷题笔记——二、2.1 vector

1 vector

1.1 vector定义

  • vector是STL的动态数组,可以在运行中根据需要改变数组的大小。
  • 以数组的形式储存,所以它的内存空间是连续的
  • 进行 vector 操作前应添加头文件 #include <vector>
  • vector是向量类型,可以容纳许多类型的数据,因此也被称为容器
    • vector是种容器,类似数组一样,但它的size可以动态改变
    • vector的元素在内存中连续排列,这一点跟数组一样。这意味着我们元素的索引将非常快,而且也可以通过指针的偏移来获取vector中的元素。
    • 连续排列也带来了弊端,当我们向vector中间插入一个数据时,整个vector的size变大,在内存中就需要重新分配空间;
    • vector采用的做法是:vector会分配额外的空间以适应size的动态增长
    • 因此,包含同样数量元素的vector和数组相比,占用的空间会更大
    • 在vector最后增加或者删除一个元素,消耗的时间是一个常数值,与vector的size无关。
  • 与其他容器(dequeslistsforward_lists)相比
    • 优点:vector在获取元素和对最后一个元素的操作效率上更高;
    • 缺点:但对于中间元素的操作,性能则相对较差。

1.2 vector初始化:

  1. 定义具有10个整型元素的向量
    • 尖括号为元素类型名,它可以是任何合法的数据类型
    • 不具有初值,其值不确定
//定义具有10个整型元素的向量(尖括号为元素类型名,它可以是任何合法的数据类型),不具有初值,其值不确定
vector<int> a(10);
  1. 定义具有10个整型元素的向量,且给出的每个元素初值为1
    • 初值为1
//定义具有10个整型元素的向量,且给出的每个元素初值为1
vector<int> a(10,1);
  1. 用向量b给向量a赋值,a的值完全等价于b的值
//用向量b给向量a赋值,a的值完全等价于b的值
vector<int> a(b);
  1. 将向量b中从0~2(共三个)的元素赋值给a,a的类型为int型
//将向量b中从0~2(共三个)的元素赋值给a,a的类型为int型
vector<int> a(b.begin(), b.begin+3);
  1. 从数组中获得初值
//从数组中获得初值
int b[7] = {1,2,3,4,5,6,7};
vector<int> a(b,b+7);

1.2 二维vector初始化:

vector还支持二维数组,但这种二维数组是通过嵌套的方式来实现

  1. vector< vector<int> > b(10, vector<int>(5));
  • //创建一个10*5的int型二维向量
  1. vector< vector<int> > b(10, vector<int>(5, 0)) ;
  • vector<vector>dp(m,vector(n,1));
    // 将dp初始化为m行n列的vector,初始化数值为1
  • //创建一个10*5的int型二维向量,其值全为0
vector<vector<int>> arr(3);
for (int i = 0; i < 3; ++i) {
    arr[i].resize(3);           //3x3 array
}
for (int i = 0; i < 3; ++i) 
    for (int k = 0; k < 3; ++k) 
        arr[i][k] = i * k;      // 赋值
arr.resize(4);                  // 二维数组包含4个变量
arr[2].resize(5);               // 第3个变量包含5个变量
  1. 插入元素
  • 若想定义A = [[0,1,2],[3,4,5]],则:
  • A.push_back里必须是vector
//正确的插入方式
vector<vector<int> > A;
//A.push_back里必须是vector
vector<int> B;
B.push_back(0);
B.push_back(1);
B.push_back(2);
A.push_back(B);
B.clear();
B.push_back(3);
B.push_back(4);
B.push_back(5);
A.push_back(B);
//错误的插入方式
vector<vector<int> > A;
A[0].push_back(0);
A[0].push_back(1);
A[0].push_back(2);
A[1].push_back(3);
A[1].push_back(4);
A[1].push_back(5);
  1. 访问元素
    vector< vector<int> > b(10, vector<int>(5));
    b[0].first;
  2. 行数、列数
  • b.size() 就是”二维数组”的行数
  • b[0].size() 就是”二维数组”的列数

1.3 vector对象的常用内置函数

1.3.0 vector属性及操作

1.3.0.1 迭代程序 Iterators
名字描述
begin返回迭代器第一个元素的指针
end返回指向迭代器最后一个元素的指针
rbegin返回迭代器逆序第一个元素的指针
rend返回迭代器逆序最后一个元素的指针
cbegin返回常量迭代器的第一个元素的指针
cend返回常量迭代器的最后一个元素的指针
crbegin返回常量迭代器逆序的第一个元素的指针
crend返回常量迭代器逆序的最后一个元素的指针
常量迭代器:
  • vector常量迭代器是用于迭代访问vector中元素的一种类型,它可以用来遍历vector中的元素,但不能修改它们。常量迭代器主要用于在不改变vector内容的情况下进行读取操作。

  • 在C++中,使用常量迭代器需要使用const_iterator类型。

std::vector<int> vec = {1, 2, 3, 4, 5};
std::vector<int>::const_iterator it;

for (it = vec.begin(); it != vec.end(); ++it) {
    // 使用常量迭代器访问元素,如输出
    std::cout << *it << " ";
}
1.3.0.2 容量 Capactiy
名字描述
size返回当前vector使用数据量的大小
ma_size返回vector最大可用的数据量
resize调整vector中的元素个数
capactiy返回vector中总共可以容纳的元素个数
empty测试vector是否是空的
reserve控制vector的预留空间
shrink_to_fit减少capactiy的size的大小
  • size返回的是当前vector中有多少元素;
  • max_size返回的是最大可用的数据量,这跟实际的硬件有关,但也并不是所有的内存空间都可用,比如下面程序中的运行的内存大x小为32GByte,但返回的结果是4GByte;
  • capacity是当前vector分配的可以容纳的元素个数,下面的代码中,vec0可以容纳13个元素,但仅包含了size(即10)个元素,还有3个元素可以放进去,当再放入超过3个元素后,vec0就会被重新分配空间;所以,capacity始终大于等于size;
  • resize把容器改为容纳n个元素。调用resize之后,size将会变为n;
    • 当n<size时,容器尾部的元素会被销毁,capacity保持不变;
    • 当size<n≤capacity时,新增加的元素都是0,capacity保持不变;
    • 当n>capacity时,size和capacity同时变为n,新增加的元素都是0;
  • empty比较简单,当vector为空时,返回1,不为空返回0;
  • shrink_to_fit,去掉预留的空间,capacity与size保持一致
1.3.0.3 元素访问Element access
名字描述
operator[]在[]中可以做运算
atvector.at(i)相当于vector[i]
front返回第一个元素的值
back返回最后一个元素的值
data返回指向vector内存数据的指针
1.3.0.4 修改器Modifiers
名字描述
assign指定vector内容
push_back在容器的最后一个位置插入元素x
pop_back删除最后一个元素
insert插入元素
erase擦除元素
swap交换两个容器的内容
clear将容器里的内容清空,size值为0,但是存储空间没有变
emplace插入元素(与insert有区别)
emplace_back在容器的最后一个位置插入新元素x(与push_back有区别)
  1. 有插入元素功能的函数有四个:push_backinsertemplaceemplace_back
    • emplace_back是在C++11中引入的,用法跟push_back完全一样,都是在vector的最后插入一个元素。
      • vec3.emplace_back(100);
      • 底层实现方式不同
        • push_back向容器尾部添加元素时,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);
        • emplace_back 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。
  • insert和emplace(C++11中引入)都可以向vector中间插入元素,但insert可以插入多个元素emplace一次只能插入一个元素
    • vec1.insert(vec1.begin(), arr, arr + 5);
    • vec1.insert(it, 3, 20);
    • vec2.insert(it2, vec3.begin(), vec3.end());
  • emplace的使用方式为:
    • iterator emplace (const_iterator pos, args…);
    • vector<int> vec0{1,2,3}; vec0.emplace(vec0.begin()+2,10); //[1,2,10,3]
  1. vector中有三种可以删除元素的操作
  • pop_back,删除最后一个元素,无返回值;
  • clear,将容器清空,size变为0,无返回值;
  • erase,通过迭代器来删除元素,可以删除一个元素,也可以删除某个范围内的元素,返回下一个位置的迭代器。
1.3.0.5 分配器Allocator
名字描述
get_allocator返回vector的内存分配器
  • get_allocator用的不是特别多,我们把使用方法讲一下。
vector<int> myvector;
int * p;
unsigned int i;

// 使用Allocator为数组分配5个元素的空间
p = myvector.get_allocator().allocate(5);


for (i=0; i<5; i++) myvector.get_allocator().construct(&p[i],i);

std::cout << "The allocated array contains:";
for (i=0; i<5; i++) std::cout << ' ' << p[i];    //[0,1,2,3,4]


for (i=0; i<5; i++) myvector.get_allocator().destroy(&p[i]);
myvector.get_allocator().deallocate(p,5);

1.3

#include <vector>
vector<int> a, b;

1.3.1 assign( , ):将b向量的0-2个元素赋值给向量a

a.assign(b.begin(), b.begin()+3);

1.3.2 assign( , ):将4个值为2的元素赋值给a向量

a.assign(4,2);

1.3.3 back():返回a的最后一个元素

a.back();

1.3.4 a[i]:返回a的第i个元素,当且仅当a存在

a[i];

1.3.5 clear():清空a中的元素

a.clear();

1.3.6 empty():判断a是否为空,空则返回true,非空则返回false

a.emptry();

1.3.7 pop_back():删除a向量的最后一个元素

a.pop_pack();

1.3.8 erase( , ):删除a中第一个(从0个算起)到第二个元素

- 也就是说删除的元素从a.begin()+1算起(包括它)
- 不包括a.begin()+3
a.erase(a.begin()+1, a.begin()+3);

1.3.9 push_back:在a向量的最后一个向量后插入一个元素,其值为5

a.push_back();

1.3.10 insert(postion, value):在a的第一个元素位置(从第0个位置算起)插入数值5

a.insert(a.begin()+1, 5);

1.3.11 insert(position, n, value):在a的第一个元素位置(从第0个算起)插入3个数,其值为5

a.insert(a.begin()+1, 3, 5);

1.3.12 insert(position, b+3, b+6):在a的第一个元素位置(从第0个算起)插入b向量的第三个元素到第5个元素(不包括b+6)

a.insert(a.begin()+1, b+3, b+6);

1.3.13 size():返回a中元素的个数

a.size();

1.3.14 capacity():返回a在内存中总共可以容纳的元素个数

a.capacity();

1.3.15 resize(n):将a的现有元素个数调整至10个,多则删,少则补,其值随机

a.resize(10);

1.3.16 resize(n):将a的现有元素个数调整至10个,多则删,少则补,其值为2

a.resize(10, 2);

1.3.17 reserve(n):将a的容量扩充至n

a.reserve(100);

1.3.18 a.swap(b):将a中的元素和b中的元素整体交换

a.swap(b);

1.3.19 == != >= > <= <:向量的比较操作

a==b;

2 顺序访问vector的机中方式

2.1对向量a添加元素的几种方式

  1. 向向量a中添加元素
vector<int>a;
for(int i=0;i<10;++i){a.push_back(i);}

  1. 从数组中选择元素向向量中添加
int a[6]={1,2,3,4,5,6};
vector<int> b;
for(int i=0;i<=4;++i){b.push_back(a[i]);}
  1. 从现有向量中选择元素向向量中添加
int a[6]={1,2,3,4,5,6};
vector<int>b;
vector<int>c(a,a+4);
for(vector<int>::iterator it=c.begin();it<c.end();++it)
{
	b.push_back(*it);
}
  1. 从文件中读取元素向向量中添加
ifstream in("data.txt");
vector<int>a;
for(int i;in>>i){a.push_back(i);}
  1. 常见错误赋值方式
    下标只能用来获取已经存在的元素,不能用来赋值
vector<int>a;
for(int i=0;i<10;++i){a[i]=i;}//下标只能用来获取已经存在的元素

2.2 从向量中读取元素

  1. 通过下标方式获取
int a[6]={1,2,3,4,5,6};
vector<int>b(a,a+4);
for(int i=0;i<=b.size()-1;++i){
	cout<<b[i]<<endl;
}
  1. 通过迭代器方式读取
 int a[6]={1,2,3,4,5,6};
 vector<int>b(a,a+4);
 for(vector<int>::iterator it=b.begin();it!=b.end();it++){
 	cout<<*it<<"  ";
 }

3 几个常用的算法

#include <algorithm>

3.1 sort(a.begin, a.end)

  • 对a中的从a.begin()(包括它)到a.end()(不包括它)的元素进行从小到大排列
sort(a.begin(), a.end());//默认升序重排
sort(a.begin(), a.end(),cmp);//将a向量按cmp函数指定的规则排列

bool cmp(int para1,int para2)//自定义为降序规则
{
    return a>b;
}

3.2 reverse(a.begin(), a.end())

  • 对a中的从a.begin()(包括它)到a.end()(不包括它)的元素倒置,但不排列,如a中元素为1,3,2,4,倒置后为4,2,3,1
reverse(a.begin(), a.end());

3.3 copy(a.begin(), a.end(), b.begin()+1)

  • 把a中的从a.begin()(包括它)到a.end()(不包括它)的元素复制到b中,从b.begin()+1的位置(包括它)开始复制,覆盖掉原有元素
copy(a.begin(), a.end(), b.begin()+1);

3.4 find(a.begin(), a.end(), 100)

  • 在a中的从a.begin()(包括它)到a.end()(不包括它)的元素中查找10,若存在返回其在向量中的位置
find(a.begin(), a.end, 10);

4 pair 结合 vector

4.1 pair:一对值可以具有不同的数据类型

pair<string , int> p;   //定义
make_pair(x,y)         //插入

4.2 定义使用pair的vector:

vector<pair<string,int>>vec; 定义使用pair的vector:
vec.push_back(make_pair(x,y));//插入pair
vec[i].first    //第i个键值对的key
vec[i].second   //第i个键值对的value

4.3 结合sort函数

static bool cmp(pair<string,int>&a,pair<string,int>&b)  
{    //注意这里的**static**
	if (a.second == b.second) {
		return a.first < b.first;
	}
	return a.second > b.second;
}
sort(vec.begin(),vec.end(),cmp);

4.4 结合map,vector和pair

 for(it = map.begin();it!=map.end();++it)
{
    temp.push_back(make_pair(it->first,it->second));
}

4.5 利用set为vector去重(vec.assign(set.begin(),set.end()))

vec = { 1, 2, 3, 4, 8, 9, 3, 2, 1, 0, 4, 8 };
set<int> st(vec.begin(), vec.end());
vec.assign(st.begin(), st.end());

参考文献

1、会敲代码的地质汪
2、浪迹天涯@wxy

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值