中缀转后缀表达式(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函数中添加更多的操作符。
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;
}