不定长数组:vector
简介
1.vector就是一个不定长数组。
2.vector是一个模板类,所以需要用vectora 或者vector vt 这样的方式来声明一个vector。
3.vector可以直接赋值,还可以作为函数的参数或者返回值,而无须像传递数组那样另外用一个变量指定元素个数。
4.它把一些常用操作“封装”在了vector类型内部。例如,若a是一个vector,可以用:
a.size( )读取它的大小;
a.resize(整数)改变大小;
a.push_back(x)向尾部添加元素;
a.pop_back( )删除尾部最后一个元素;
a.clear( )清空。
例题 木块问题(The Blocks Problem)
题意:从左到右有n个木块,编号为0~n-1 ,要求模拟一下四种操作(a,b是木块的编号)
- 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所在木块堆顶部
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 101;
vector<int>pile[maxn];
int n ;
void find_block(int a , int &p , int &h)//找木块儿 a 所在的pile和heighet , 以引用的形式返回调用
{
for(p = 0 ; p < n ; p ++)//找到a在第几堆
{
for(h = 0 ; h < pile[p].size() ; h ++)//找到a在第几堆的哪一个高度
if(pile[p][h] == a)
return ;
}
}
void clear_above(int p , int h)//把第p堆高度为h的木块上方的所有木块返回原位
{
for(int i = h + 1 ; i < pile[p].size() ; i ++)
{
int b = pile[p][i];//用b来标记高度h+1
pile[b].push_back(b);//将高度为h以上的木块一个一个的放入到堆pile中
}
pile[p].resize(h+1);//调整第p堆的高度
}
void pile_onto(int p , int h , int p2)//把第p堆高度为h及其上方的木块儿整体移动到p2堆的顶部
{
for(int i = h ; i < pile[p].size() ; i ++)
pile[p2].push_back(pile[p][i]);//将第p堆的从高度为h以上的木块移到第p2对顶上
pile[p].resize(h);//在移动之后接着变更第p堆的高度
}
void print()
{
for(int i = 0 ; i <n ; i ++)
{
printf("%d:",i);
for(int j = 0 ; j < pile[i].size() ; j ++)
printf(" %d",pile[i][j]);
printf("\n");
}
}
int main()
{
int a , b ;
string s1 ,s2;
cin>>n;
for(int i = 0 ; i < n ; i ++)
pile[i].push_back(i);
while(cin>>s1>>a>>s2>>b)
{
int pa , pb , ha , hb;
find_block(a,pa,ha);
find_block(b,pb,hb);
if(pa == pb) //处理非法指令
continue;
if(s2 == "onto")//如果是onto的话肯定是将b上方的木块全部归位
clear_above(pb,hb);
if(s1 == "move")
clear_above(pa,ha);
pile_onto(pa,ha,pb);
}
print();
return 0 ;
}
困惑
把第p堆高度为h的木块上方的所有木块返回原位
void clear_above(int p , int h)
{
for(int i = h + 1 ; i < pile[p].size() ; i ++)
{ int b = pile[p][i]; pile[b].push_back(b); }
pile[p].resize(h+1);
}
把这些木块放回原位是放回的哪里,是放回到不同的木块堆上面吗?
总结
数据结构的核心是vectorpile[maxn],所有的操作都是围绕它的。vector就像一个二维数组,只是第一维的大小是固定的(不超过maxn),但第二维的大小是不固定的。上述代码还有一个值得学习的技巧:输入一共有4种指令但如果完全独立地处理各自指令,代码就会变得冗长而且易错。更好的方法是提出指令之间的共同的点,编写函数以减少重复代码。vector之间可以直接赋值,或者作为函数的返回值。