【问题标题】:Wrong answer from a program (infix notation->postfix notation) in CC中程序(中缀表示法->后缀表示法)的错误答案
【发布时间】: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));
}

[结果]

结果:1​​9

结果 : -61 // 这应该是 '195'。

结果:0

【问题讨论】:

  • 与您的问题无关,但即使字符串以 null 结尾,也不意味着 NULLNULL 用于空 指针。空终止字符是 '\0' 或其等效整数 0
  • 至于您的问题,请花一些时间阅读how to debug small programs,并了解如何使用调试器逐行执行代码,同时监控变量及其值。我还建议您打印出来,例如pos2 确保后缀表达式正确。
  • 嗯...有趣的是-61 + 256 == 195。签名溢出?
  • @Someprogrammerdude 谢谢你的建议!代码来自一本C语言数据结构的教程书。我添加了一些部分来制作一个自己具有该功能的程序。

标签: c stack


【解决方案1】:

线索是61+195 = 256。这意味着在某个地方,您的计算被保存为字符。好像是element

typedef element int;

【讨论】:

  • 谢谢!我将 'char' 更改为 'int' 并且效果很好。我忘记了我没有改变零件来制作程序......
猜你喜欢
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
  • 2016-11-04
  • 2016-07-23
  • 1970-01-01
  • 2014-08-26
  • 2011-09-23
相关资源
最近更新 更多