题目:在栈操作中添加几个命令,分别用于在不弹出元素的情况下打印栈顶元素;复制栈顶元素;交换栈顶两个元素的值。另外增加一个命令用于清空栈。
自我解答:
void printTop(void)
{
if(sp > 0)
printf("the top element of the stack is %f\n", val[sp - 1]);
else
printf("error: stack empty");
}
double copyTop(void)
{
if(sp > 0)
return val[sp - 1];
else
{
printf("error: stack empty");
return 0.0;
}
}
void swap(void)
{
double temp;
if(sp > 1)
{
temp = val[sp - 1];
val[sp - 1] = val[sp - 2];
val[sp - 2] = temp;
}
else
printf("error: the size of stack is less than 2\n");
}
void emptyStack(void)
{
sp = 0;
}
所有对栈的操作都可以通过两个外部变量 val和sp来实现
参考答案:
#include <stdio.h>
#include <math.h> /* for atof() */
#define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
int getop(char []);
void push(double);
double pop(void);
void clear(void);
/* reverse Polish calculator */
int main()
{
int type;
double op2;
char s[MAXOP];
while((type = getop(s)) != EOF)
{
switch (type)
{
case NUMBER:
push(atof(s));
printTop();
printf("%f\n", copyTop());
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
op2 = pop();
push(pop() - op2);
break;
case '/':
op2 = pop();
if(op2 != 0.0)
push(pop() / op2);
else
printf("error: zero divisor\n");
break;
case '?': /* print top element of the stack */
op2 = pop();
printf("\t%.8g\n", op2);
push(op2);
break;
case 'c': /* clear the stack */
clear();
break;
case 'd': /* duplicate top elem. of the stack */
op2 = pop();
push(op2);
push(op2);
break;
case 's': /* swap the top two elements */
op1 = pop();
op2 = pop();
push(op1);
push(op2);
break;
case '\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
return 0;
}
现有的换行操作符将弹出栈顶元素并打印。我们新增的操作符“?”将弹出栈顶元素并打印,再把它压入堆栈。“?”操作符不会像换行操作符那样把栈顶元素永久地弹出堆栈,并采用“出栈,打印,入栈”这一方案的原因是为了避免主程序直接对堆栈和堆栈指针变量(sp)进行操作。
复制栈顶元素的操作过程是:先弹出栈顶元素,再把它压入两次。
交换栈顶两个元素的操作过程是:先依次弹出两个栈顶元素,再按相反的顺序把它们压入堆栈。
清除堆栈内容的工作很容易完成:把sp设置为零即可。我们增加了一个完成这项工作的函数,并把它与push和pop放置在一起。这样做的目的是只允许这三个函数维护堆栈、访问堆栈及堆栈指针变量。
/* clear: clear the stack */
void clear(void)
{
sp = 0;
}
总结:
自我解答和参考答案中的实现完成的功能虽然类似,但是参考答案中完全是借用了push和pop函数进行,而自我解答中是增加了函数实现,操作了堆栈和堆栈指针sp。所以对题目中的“不弹出元素”的理解不是指不能用push和pop函数,而是弹出后再压回不影响原有的堆栈结构。自我解答中对不弹出元素的理解是“不能使用push和pop”函数,所以采用了直接操作堆栈和堆栈指针。