中缀表达式是最自然、最易被人类理解的表达方式,但是计算机处理起来并不显得方便,这时,后缀表达式就发挥作用了
例如:计算表达式(a + b) * (c + d)的值,程序里需要不断的判断运算符的优先级,先计算括号里的子表达式
假如我们将上述表达式转换为后缀表达式:a b + c d + *,你会发现现在是不需要括号了
这时我们只需要扫描表达式,碰到数据就入栈,碰到运算符就出栈两个数据,计算完成之后将结果再入栈,最后栈中保存的是表达式的最终结果
这就是后缀表达式的用途之一
本算法只完成中缀表达式到后缀表达式的转换,且假设表达式中只会出现空白符 数据 + - * /四种运算符和括号,栈作为辅助工具
#include <stdio.h>
#include <string.h>
#define MAX 100
#define push(stk, val) stk->data[stk->size++] = val
#define pop(stk) stk->data[--stk->size]
#define top(stk) stk->data[stk->size - 1]
#define empty(stk) stk->size == 0
#define init(stk) stk->size = 0
struct stack
{
int data[MAX];
int size;
};
void convert(char *exp)
{
char str[MAX];
int i = 0, j = 0;
struct stack stk;
struct stack *pt = &stk;
init(pt);
while (exp[i] != '\0')
{
switch (exp[i])
{
case ' ':
case '\t':
case '\n':
break;
case '+':
case '-':
while (!empty(pt) && top(pt) != '(')
{
str[j++] = pop(pt);
}
push(pt, exp[i]);
break;
case '*':
case '/':
if (!empty(pt) && (top(pt) == '*' || top(pt) == '/'))
{
str[j++] = pop(pt);
}
push(pt, exp[i]);
break;
case '(':
push(pt, exp[i]);
break;
case ')':
while (!empty(pt) && top(pt) != '(')
{
str[j++] = pop(pt);
}
pop(pt);
break;
default:
str[j++] = exp[i];
break;
}
++i;
}
while (!empty(pt))
{
str[j++] = pop(pt);
}
str[j] = '\0';
strcpy(exp, str);
}
int main(void)
{
char exp[MAX] = "a + b * c - (d + e / f) * g";
convert(exp);
printf("%s\n", exp);
return 0;
}