【发布时间】:2017-05-24 11:55:11
【问题描述】:
我编写了一个程序,通过在 C 中使用堆栈将中缀表示法更改为后缀表示法。
我做了一个打印后缀表示法结果的函数(来自中缀表示法)。
但是,符号的结果是错误的。这应该是“195”,但其结果是“-61”。
其他记法的结果都是对的,但只有记法(op2)有这个问题。
我应该怎么做才能解决这个问题?
这是我的代码:
typedef char element;
typedef struct {
element stack[MAX_STACK_SIZE];
int top;
} StackType;
void init(StackType *s) {
s->top = -1;
}
int is_empty(StackType *s) {
return (s->top == -1);
}
int is_full(StackType *s) {
return (s->top == (MAX_STACK_SIZE - 1));
}
void push(StackType *s, element item) {
if (is_full(s)) {
fprintf(stderr, "FULL STACK ERROR\n");
return;
}
else s->stack[++(s->top)] = item;
}
element pop(StackType *s) {
if (is_empty(s)) {
fprintf(stderr, "EMPTY STACK ERROR\n");
exit(1);
}
else return s->stack[(s->top)--];
}
int eval(char exp[]) {
int op1, op2, value, i = 0;
int len = strlen(exp);
char ch;
StackType s;
init(&s);
for (i = 0; i < len; i++) {
ch = exp[i];
if (ch != '+' && ch != '-' && ch != '*' && ch != '/') {
value = ch - '0';
push(&s, value);
}
else {
op2 = pop(&s);
op1 = pop(&s);
switch (ch) {
case '+': push(&s, op1 + op2); break;
case '-': push(&s, op1 - op2); break;
case '*': push(&s, op1 * op2); break;
case '/': push(&s, op1 / op2); break;
}
}
}
return pop(&s);
}
char* infix_to_postfix(char exp[]) {
int i = 0, j = 0;
char ch, top_op;
int len = strlen(exp);
char *ex = (char *)malloc(sizeof(char)*(len + 1));
StackType s;
init(&s);
for (i = 0; i < len; i++) {
ch = exp[i];
switch (ch) {
case '+': case '-': case '*': case '/':
while (!is_empty(&s) && (prec(ch) <= prec(peek(&s)))) {
ex[j++] = pop(&s);
}
push(&s, ch);
break;
case '(':
push(&s, ch);
break;
case ')':
top_op = pop(&s);
while (top_op != '(') {
ex[j++] = top_op;
top_op = pop(&s);
}
break;
default:
ex[j++] = ch;
break;
}
}
while (!is_empty(&s)) {
ex[j++] = pop(&s);
}
ex[j] = NULL;
return ex;
}
void main() {
char *op1 = "(9-(3+2))*3+4*((4+2)/3)-1";
char *op2 = "(4*5-3)/3+((2+5*7)-8+9)*5";
char *op3 = "7*3-7-4+1/3+6-8*2";
char *pos1, *pos2, *pos3;
pos1 = infix_to_postfix(op1);
pos2 = infix_to_postfix(op2);
pos3 = infix_to_postfix(op3);
printf(" Result : %d\n", eval(pos1));
printf(" Result : %d\n", eval(pos2));
printf(" Result : %d\n", eval(pos3));
}
[结果]
结果:19
结果 : -61 // 这应该是 '195'。
结果:0
【问题讨论】:
-
与您的问题无关,但即使字符串以 null 结尾,也不意味着
NULL。NULL用于空 指针。空终止字符是'\0'或其等效整数0。 -
至于您的问题,请花一些时间阅读how to debug small programs,并了解如何使用调试器逐行执行代码,同时监控变量及其值。我还建议您打印出来,例如
pos2确保后缀表达式正确。 -
嗯...有趣的是
-61 + 256 == 195。签名溢出? -
@Someprogrammerdude 谢谢你的建议!代码来自一本C语言数据结构的教程书。我添加了一些部分来制作一个自己具有该功能的程序。