举例1:(4+5)*2-3 = 9*2-3 = 15
如果写成后缀表达式就有45+2*3-,请大家观察一下,其实转化过程就是把符号写在要计算的数后面,4+5转换为45+
那么对于这个例子的计算就有45+2*3- = 92*3- = 18 3- = 15,这个例子中每个符号前仅有两个数字,比较简单好懂。
举例2:5+(3-1)*3+9/3 = 14,写成后缀表达式有531-3*+93/+,这个例子就相对上一个复杂一点,来一步步分析一下
先去括号5+(31-)*3+9/3,再处理乘除法,5+((31-)3*)+(93/),再去处理加减法,(分两步清晰一点)
(5((31-)3*)+)+(93/),((5((31-)3*)+)(93/)+)然后去括号,531-3*+93/+
就得到了后缀表达式。再来计算
531-3*+93/+ = 523*+93/+ = 56+93/+ = 1193/+ = 113+ = 14
请大家观察一下,其实就是从左到右进入字符串找运算符,然后处理这个运算符的前两位数字,然后将处理后的字符放回原位,这种转换,搭配上栈的使用,可以不用管括号,直接对后缀表达式进行处理求值。
继续对例2进行分析,为了从左到右处理,先把内容从后往前压入栈1,+/39+*3-135,处理栈顶元素,不是符号就出栈,入栈2,此时有栈2为 531,遇到运算符号时对栈2进行处理,取出前两位,运算完后压栈,即52(注意 ,被减/除数是第二个出栈的元素)再取数字523,遇到*再处理,后面的栈2种存储的依次为56,11,1193,113,14,方法以此类推,直到栈1为空,完全处理。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct STNode
{
int data;
struct STNode* next;
}STNode, *StackLink;
void Push(StackLink* S, int data);
int Pop(StackLink* S);
int Compute(int a, int b, char c);
int main()
{
char ch[100];
int i;
StackLink S = NULL, Q = NULL;
int a, b;
char c;
scanf("%s", ch);
for (i = strlen(ch)-1; i >= 0; i--)
{
if (ch[i] >= '0' && ch[i] <= '9')
{
Push(&S, ch[i] - '0');
}
else
{
Push(&S, ch[i]);
}
}
while (S != NULL)
{
if (S->data >= 0 && S->data <= 9)
{
Push(&Q, Pop(&S));
}
else
{
b = Pop(&Q);
a = Pop(&Q);
c = Pop(&S);
Push(&Q, Compute(a, b, c));
}
}
printf("%d", Q->data);
return 0;
}
void Push(StackLink* S, int data)
{
StackLink q = (StackLink)malloc(sizeof(STNode));
q->data = data;
q->next = (*S);
(*S) = q;
}
int Pop(StackLink* S)
{
StackLink q = (*S);
int data = q->data;
(*S) = (*S)->next;
free(q);
return data;
}
int Compute(int a, int b, char c)
{
int answ;
if (c == '+')
{
answ = a + b;
}
else if (c == '-')
{
answ = a - b;
}
else if (c == '*')
{
answ = a * b;
}
else if (c == '/')
{
answ = a / b;
}
return answ;
}