数据结构-vector
来源:互联网 发布:卫生巾政治环境知乎 编辑:程序博客网 时间:2024/06/06 07:22
vector是不定长数组,也就是说它的长度是不固定的,简单地说就是“按需分配”。这听上去似乎有点麻烦,但在声明数组时如果我们并不清楚数组的长度,并且简单粗暴地使用#define MAXN 1000000
会导致内存失去了梦想——就算不,仍有大量的内存成了咸鱼。这个时候,我们就需要vector数组。
先看一道例题:
从左到右有n个木块,编号为0~n-1,要求模拟以下四种操作:
- move a onto b:把a和b上方的木块全部归位,然后把a摞在b上面。
- move a over b:把a上方的木块全部归位,然后把a放在b所在木块堆的顶部。
- pile a onto b:把b上方的木块全部归位,然后把a及上面的木块整体摞在b上面。
- pile a over b:把a及上面的木块整体摞在b所在木块堆的顶部。
遇到quit时终止一组数据。a和b在同一堆的指令时非法指令,应当忽略。
所有操作结束后,输出每个位置的木块列表,按照从底部到顶部的顺序排列。
(出自UVa 101,小紫书p110)
由于每个木块堆的最大高度并没有限制,如果开一个a[n][n]的数组,显然浪费了很多空间,并且出题人很可能会故意卡MLE,于是我们需要一个“按需分配”数组。
链表
在介绍vector前,先提一下链表。
在c语言中,我们并没有c++丰富的STL,也就是说需要人工实现不定长数组:
struct Node { int num; //用于储存数据 Node* next; };
这段代码声明了一个结构体Node,它包含了一个int型变量num和一个指针next,让我们有请灵魂画师来帮助我们理解。
我们的链表是由若干个这样的“小块”组成的,由于创建的“小块”之间没有任何联系,所以我们需要用一个指针next将它们连接到一起,也就是用next指向下一个“小块”,这样我们就能将它们“链”在一起。
每一个next都指向下一个块的地址,我们只需要访问当前块的next储存的地址,就可以到达下一个块。
由于我们只用在需要的时候申请一个新的块,并把它和之前的链表连在一起,所以可以达到不定长数组的作用。
但显然,构造一个链表十分麻烦,并且鄙人已经基本忘了怎么写链表,所以我们需要一个C艹。(c语言的链表构建我会在之后补上(flag++))
vector
在C++中,我们可以用vector来代替链表,这需要
#include <vector>
在vector中,我们(暂时)不需要再思考指针和它的小伙伴们,可以把vector看作一个正常的数组:
也就是说它的空间是“连续”的。
我们可以用
vector <int> v;
声明一个vector数组,它的元素为int型。当然,你也可以换成double型或者string型甚至是结构体。
vector为我们提供了以下操作:
v.push_back(n); //将元素n加入到v的尾部 v.pop_back(); //将v的末端的元素删除 v.empty(); //判断数组是否为空,若为空则返回真,否则返回假 v.size(); //返回v中元素的数量 v.resize(n); //将v的长度设为n
如果我们想访问v中的元素,只需要像数组一样访问下标即可:
ans=v[i]; num=v[i]+v[i+1];
这时候,我们可以解决前面的例题了。
代码示例
#include <iostream>#include <string>#include <vector>using namespace std;const int MAXN=10000;vector <int> v[MAXN];int n;int find(int a,int& p,int& h) //寻找木块a(或b)所在位置和高度{ p=v[a][0]; for(h=1;h<v[p].size();h++) { if(v[p][h]==a) return 0; }}void clear(int p,int h) //将位置p高度h的木块上方的所有木块归位{ for(int i=h+1;i<v[p].size();i++) { int j=v[p][i]; v[j][0]=j; } v[p].resize(h+1);}void move(int p1,h1,p2) //将位置p1高度h1的木块及上方的所有木块移到位置p2的顶端{ for(int i=h1;i<v[p1].size();i++) { int j=v[p1][i]; v[p2].push_back(j); v[j][0]=p2; } v[p1].resize(h1);}int main(){ int a,b; string s1,s2; while(cin>>n>>s1) { for(int i=0;i<n;i++) //初始化v { v[i].clear(); v[i].push_back(i); //v[i][0]保存木块i所在的位置 } while(s1!="quit") { cin>>a>>s2>>b; int p1,h1,p2,h2; find(a,p1,h1); find(b,p2,h2); if(p1!=p2) { if(s2=="onto") clear(p2,h2); if(s1=="move") clear(p1,h1); move(p1,h1,p2); } cin>>s1; } for(int i=0;i<n;i++) //一组数据结束,打印木块列表 { cout<<i<<":"; for(int j=1;j<v[i].size();j++) cout<<v[i][j]<<" "; cout<<endl; } } return 0;}
鄙人用v[i][0]来保存木块i所在的位置(初始为i),这样在每次find的时候可以减少一次for循环查找木块i的位置,避免最坏情况下find为O(n²)而导致超时。
迭代器
还记得之前说的“我们(暂时)不需要再思考指针和它的小伙伴们”么?
是的,我们只是暂时不需要,但事实上还有个叫做“迭代器”的设定。
由于不(wo)可(jiu)抗(shi)力(lan)的因素,此部分之后再更新……
PS:
写这篇的时候临近国庆,于是我咕了将近半个月,虽然打算国庆结束后就补完迭代器的部分,然而我很快就发烧在床上瘫了两天…就这么先扔上来吧(强颜欢笑)
…什么?还有链表?
- 数据结构-vector
- 【数据结构】vector用法总结
- 数据结构之Vector
- 浅谈数据结构vector
- 数据结构List之Vector
- 第四章数据结构-Vector
- 第四章数据结构-Vector
- Java 数据结构 --> Vector 类
- 数据结构之vector
- 【一】 数据结构之Vector
- 数据结构之vector&list
- Java数据结构--跟着api学数据结构--Vector
- java数据结构之向量Vector
- 算法导论数据结构篇---vector
- 数据结构—向量(vector)-数组
- 数据结构-Vector实现(C++)
- Java数据结构 ArrayList、LinkList、Vector
- 数据结构_1:线性表: Vector
- date.js
- 58 同城 iOS 客户端搜索模块组件化实践
- A Pub/Sub based HTTP communication method in complex network environments
- ucos-iii学习之循环轮转调度及调度的内部实现
- jquery-ul-li实现分页功能
- 数据结构-vector
- 第四周-项目2
- Delphi 用ADO调用oracle的包中的过程,报 列不存在 的错误
- mac双系统用磁盘工具合并windows分区后 开机还会 出现win分区
- html之js字符串处理方法
- eclipse中代码每行多了换行符
- 关于分划那点破事
- Windows进程间通信-共享内存
- 学习Unet的一些过程