中缀转后缀表达式(c实现)

中缀转后缀表达式(c实现)


实现的方法很简单:就是用栈来实现。

  • 如果是数,我们就直接输出
  • 是操作符,我们弹出栈中比它优先级更高的操作符,然后再将它入栈
  • 是 ’ ( ‘ ,我们弹出栈中 ’ ) ’ 以前的所有操作符
  • 遇见 ‘ - ‘ 时,要判断它是负号还是减号
  • 遇见 ’ \n ’ ,弹出栈中所有的操作符
为了清晰美观起见,我们可以在输出的后缀表达式中,在每个运算符或操作数之间加上一个空格
下面是代码,都有很清晰的注释:

首先是主函数,控制整个转换过程,当然也可以用一个函数来实现,不过这里是为了说明问题,没有必要那样
/*  将中缀表达式转换为后缀表达式  */
int main(int argc, const char *argv[])
{
    int c;

    while ((c = getchar()) != EOF)
        if (isdigit(c) || c == '.') {    /*  是数,就直接输出  */
            putchar(c);
            while (isdigit(c = getchar()) || c == '.')
                putchar(c);
            putchar(' ');
            ungetc(c, stdin);     /*  将多读入的字符压回到输入中  */
        } else if (op_prior(c) || c == ')') {
            if (isempty() && c != '-')
                push(c);
            else if (c == ')') {     /*  遇见')',弹出栈中'('以前的所有运算符  */
                while (!isempty() && top() != '(')
                    printf("%c ", pop());
                if (!isempty())
                    pop();
            } else {
                if (c == '-') {     /*  判断'-'是负号还是减号  */
                    if (isdigit(c = getchar())) {
                        printf("-%c", c);
                        while (isdigit(c = getchar()) || c == '.')
                            putchar(c);
                        putchar(' ');
                        ungetc(c, stdin);
                        continue;
                    } else {
                        ungetc(c, stdin);
                        c = '-';
                    }
                }     /*  栈顶运算符的优先级应当低于当前读入的运算符的优先级  */
                while (!isempty() && top() != '(' && op_prior(top()) >= op_prior(c))
                    printf("%c ", pop());
                push(c);
            }
        } else if (c == '\n') {    /*  遇见换行符时,弹出栈中所有的运算符  */
            while (!isempty())
                printf("%c ", pop());
            putchar('\n');
        }
    return 0;
}
对于如何返回对应操作符的优先级,我们可以用简单的数字来表示操作符的优先级,如果你想要实现更多的功能,你可以直接在op_prior函数中添加更多的操作符。
/*  op_prior函数:返回对应运算符的优先级  */
int op_prior(int c)
{
    switch(c) {
    case '(':
        return 3;
        break;
    case '*': 
    case '/': 
    case '%':
        return 2;
        break;
    case '+': 
    case '-':
        return 1;
        break;
    default:
        return 0;
        break;
    }
}
最后便是所用到的主要的数据结构——栈了,这里很容易想到的便是用数组来实现堆栈,而非链表。原因也很简单:在每一时刻,栈中的操作符数量总不会太多,栈空间用尽的可能性非常小。
#define MAXVAL 100

static int val[MAXVAL];    /*  值栈  */
static int sp = -1;    /*  栈顶指针  */

void push(int c)
{
    if (!isfull())
        val[++sp] = c;
    else
        printf("stack is full\n");
}

int pop(void)
{
    if (!isempty())
        return val[sp--];
    else {
        printf("stack is empty\n");
        return 0;
    }
}

int top(void)
{
    if (!isempty())
        return val[sp];
    else {
        printf("stack is empty\n");
        return 0;
    }
}

int isfull(void)
{
    return sp == MAXVAL - 1;
}

int isempty(void)
{
    return sp == -1;
}

猜你喜欢

转载自blog.csdn.net/qq_41145192/article/details/80547708