堆栈的使用
时间限制:1 秒
内存限制:32 兆
特殊判题:否
提交:4344
解决:1249
-
题目描述:
-
堆栈是一种基本的数据结构。堆栈具有两种基本操作方式,push 和 pop。Push一个值会将其压入栈顶,而 pop 则会将栈顶的值弹出。现在我们就来验证一下堆栈的使用。
-
输入:
-
对于每组测试数据,第一行是一个正整数 n,0<n<=10000(n=0 结束)。而后的 n 行,每行的第一个字符可能是'P’或者'O’或者'A’;如果是'P’,后面还会跟着一个整数,表示把这个数据压入堆栈;如果是'O’,表示将栈顶的值 pop 出来,如果堆栈中没有元素时,忽略本次操作;如果是'A’,表示询问当前栈顶的值,如果当时栈为空,则输出'E'。堆栈开始为空。
-
输出:
-
对于每组测试数据,根据其中的命令字符来处理堆栈;并对所有的'A’操作,输出当时栈顶的值,每个占据一行,如果当时栈为空,则输出'E’。当每组测试数据完成后,输出一个空行。
-
样例输入:
-
3 A P 5 A 4 P 3 P 6 O A 0
-
样例输出:
-
E 5 3
-
对题目的理解:
1、关于“堆栈”的理解,首先我们会想“堆栈”和“堆”、“栈”是什么关系?这个问题会越想越复杂的啦,网上有些资料说“堆栈”简称“栈”,但在这个题目里呢,就不必纠结它到底是个什么东西,有什么特征,题目里面已经给出了它的定义和特征,这是题目里的定义和特征,做这个题目也只需要题目里的定义和特征,定义是一种数据结构,特征就是Pop和Push。
2、知道了题目中”堆栈“的特征就需要来实现了,是使用数组还是连接,栈在大小明确的情况下使用的是数组。我们使用数组。定义数组大小MAXSIZE = 10001。
在C++中的stack是deque(双端队列)的适配器,使用的是
分段数组的实现方式。
vector使用的数组实现方式,它的自增功能采用数组空间用完,然后分配一个更大的空间,把之前的数组拷贝进去,释放之前的数组空间。可以探究一下为什么要使用数组实现方式?实验室一位牛掰师兄给出了他的看法,deque是头尾删除,vector需要随机访问,数组结构随机访问时间复杂度为0(1)。
C++版本:
#include <stdio.h>
#include <iostream>
#define MAXSIZE 10001
using namespace std;
int stack[MAXSIZE];
int push(int i)
{
int value;
cin>>value;
stack[++i] = value;
return i;
}
void getop(int i){
if(i < 0)
printf("E\n");
else
printf("%d\n",stack[i]);
}
int pop(int i){
if(i >= 0)
i--;
return i;
}
int main(void)
{
int n;
int top;
char d;
while(cin >> n && n != EOF ){
top = -1;
int i;
for(i = 1; i <= n; ++i){
char c;
cin>>c;
switch(c){
case 'A':getop(top);break;
case 'P':top = push(top);break;
case 'O':top = pop(top);break;
}
}
printf("\n");
}
return 0;
}
C版本:
#include <stdio.h>
#define MAXSIZE 10001
int stack[MAXSIZE];
int top;
void push()
{
int value;
getchar();
scanf("%d",&value);
stack[++top] = value;
}
void gettop(){
if(top < 0)
printf("E\n");
else
printf("%d\n",stack[top]);
}
void pop(){
if(top >= 0)
top--;
}
int main()
{
int n;
while(scanf("%d",&n) != EOF && n !=0 ){
getchar();
top = -1;
for(int i = 1; i <= n; ++i){
char c;
scanf("%c",&c);
switch(c){
case 'A':
gettop();
break;
case 'P':
push();
break;
case 'O':
pop();
}
while(getchar()!='\n');//为什么这样使用,是因为案例中有一行字母后面<span style="white-space:pre"> </span>//不是<span style="font-family: 'MicroSoft Yahei', Helvetica, Arial, Georgia, Simsun; ">直接的换行符,还有一个空格符,</span>
}
printf("\n");
}
return 0;
}
C版本的代码在VS2012里面编译会出现编译错误,使用gcc编译器编译在c89下面会出问题,在c99问题里面是完全OK,出现这种问题的原因是c89不允许在for循环里定义变量,必须放在方面,置于VS2012出问题的原因更奇怪,把定义放for语句前面也会报错,据一位牛掰师兄说,可能是因为VS的编译器要求函数里的变量都需要在函数内部的最前面定义(我试了一下这个不太准,其事for循环体内部也是可以定义变量的),但是如果把for语句内部的变量定义语句放到函数的开头处,编译将顺利通过。
题外知识——栈 1、栈是什么?后进先出的数据结构。 与同学讨论遇到诸多问题: 1、scanf和cin输入字符的表现,只能输入可见字符,cin为什么遇到空格会停止输入,cin是如何从输入缓冲区里提取输入的字符,并可以判定是不是自己所需输入字符,并且得到自己的输入结果赋给变量? 2、变量不初始化变量就使用在VS里运行会报错,但是在gcc里运行时不会报错,VS到底是什么原因导致了运行时的错误,在两种环境下都是可以获取变量的地址的,就代表变量在定义时就已经分配了空间。 3、case里面是不能初始化一个变量,但是能够定义一个变量,为什么会出现这个差异?