我试图递归地实现LIFO堆栈,而不使用数组。该程序将字符串和整数作为输入,并具有一些命令-即push <int>
pop
empty
top
和quit
。
除pop
之外的所有内容都对我有效,而pop
仅对部分内容有效。如果只弹出一个int很好,但是除此之外,即使不是,它也会返回一个stack is empty
。我知道为什么会发生这种情况,但不确定如何解决。
int stack(int top, int last) {
int m = read_symbol();
if (m != READ_FAIL) {
if (m == PUSH_SYMBOL) {
int n = read_int();
top = stack(n, top);
} else if (m == POP_SYMBOL) {
if (top == INT_MIN) {
printf("pop error - stack is empty\n");
top = stack(INT_MIN, INT_MIN);
} else {
top = stack(last, INT_MIN);
}
} else if (m == TOP_SYMBOL) {
if (top == INT_MIN) {
printf("top error - stack is empty\n");
} else {
printf("top - %d\n", top);
}
top = stack(top, last);
} else if (m == EMPTY_SYMBOL) {
if (top == INT_MIN) {
printf("stack is empty\n");
} else {
printf("stack is not empty\n");
}
top = stack(top, last);
} else if (m == QUIT_SYMBOL) {
if (top != INT_MIN) {
printf("quit error - stack is not empty\n");
top = stack(top, last);
} else {
printf("goodbye\n");
}
}
}
return top;
}
递归返回top
变量,因此一切正常。但是当我做类似的事情
push 1
push 2
push 3
top
pop
top
pop
top
返回的输出是
top - 3
top - 2
top error - stack is empty (SHOULD BE 1)
我尝试了各种不同的方法,但是我无法解决它。实际上,我只是为了解决此问题而引入了last
参数,即使没有last
,其余的实现也可以正常工作,但目前看来该参数有效,但仅适用于一个pop
命令因为下一个递归级别将last
设置为INT_MIN
,如果再次使用top
,则将其设置为pop
,因此错误的stack is empty
消息
任何指针或帮助将不胜感激。
编辑:INT_MIN
是指C99 limits.h
INT_MIN
,它是-(2 ^ 32-1)
答案 0 :(得分:0)
所以我想我已经解决了为什么要这样做的问题,首先,我稍微重写了您的函数,以便使用转换语句来实现紧凑性(这不是解决问题的方法):
int stack(int top, int last) {
switch(read_symbol()) {
// push n
case PUSH_SYMBOL:
return stack(read_int(), top);
// pop
case POP_SYMBOL:
if (top == INT_MIN) {
printf("pop error - stack is empty\n");
return stack(INT_MIN, INT_MIN);
}
return stack(last, INT_MIN);
// top
case TOP_SYMBOL:
if (top == INT_MIN)
printf("top error - stack is empty\n");
else
printf("top - %d\n", top);
return stack(top, last);
// empty
case EMPTY_SYMBOL:
if (top == INT_MIN)
printf("stack is empty\n");
else
printf("stack is not empty\n");
return stack(top, last);
// quit
case QUIT_SYMBOL:
if (top != INT_MIN) {
printf("quit error - stack is not empty\n");
return stack(top, last);
}
printf("goodbye\n");
case READ_FAIL: // error handling
default:
return top;
}
}
然后我遵循了假定的调用堆栈:
stack(INT_MIN, INT_MIN) receives PUSH 1 -> stack(1, INT_MIN)
stack(1, INT_MIN) receives PUSH 2 -> stack(1, 2)
stack(1, 2) receives PUSH 3 -> stack(3, 2)
stack(3, 2) receives TOP -> stack(3, 2)
stack(3, 2) receives POP -> stack(2, INT_MIN)
stack(2, INT_MIN) receives TOP -> stack(2, INT_MIN)
stack(2, INT_MIN) receives POP -> stack(INT_MIN, INT_MIN)
stack(INT_MIN, INT_MIN) receives TOP => ERROR
这里的问题非常简单,pop调用stack(x,INT_MIN),这在您的代码中意味着在弹出之后,堆栈的大小仅为1(或零)。不使用前一个调用堆栈中的数据。
答案 1 :(得分:-4)
在其他情况下,如果(m == POP_SYMBOL){}更改
if (top == INT_MIN)
到
if (top < INT_MIN)
,并让我知道它是否对您有用,因为变量“ top”的逻辑不正确(例如)我们可能会根据逻辑认为变量“ top”被破坏,而实际上它会在下一次迭代中被破坏。这样做对您不起作用,然后发布INT_MIN的值(可能是#define-ed值)