我们把平时所用的标准四则运算表达式叫做中缀表达式,而对于四则运算而言,括号和加减乘除使得问题对于计算机非常复杂,为了有效地处理它们,波兰逻辑学家想到了一种不需要括号的后缀表达式,我们称之为逆波兰。
中缀表达式:9+(3-1)*3+10/2
后缀表达式:9 3 1 - 3 * + 10 2 / +
后缀表达式计算结果
规则:从左到右遍历表达式的每个数字和符号,遇到数字则进栈,遇到是符号,就将处于栈顶的两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果为止。
9 3 1 - 3 * + 10 2 / +
1.初始化一个空栈,用来对要运算的数字进行使用
2.将9 3 1 进栈。
3.接下来是“-”,将1 出栈作为减数,3出栈作为被减数,运算3-1得2,2入栈。
4.将3进栈。
5.遇见“*”,将3和2出栈相乘得6,6进栈。
6.后面是“+”,6和9出栈相加得15,进栈。
7.10和2进栈。
8.符号“/”,2和10出栈,10与2相除得5,进栈。
9.“+”,15和5出栈相加得20,进栈。
10.20出栈。
得原式的结果为20。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
typedef double ElemType; //用double型
typedef struct
{
int maxsize;
ElemType *top;
ElemType *base;
}SqStack;
void init(SqStack* s, int n)
{
s->base = (ElemType*)malloc(sizeof(ElemType)*n);
if( !s->base )
{
exit(0);
}
s->maxsize = n;
s->top = s->base;
}
void push(SqStack* s, ElemType a)
{
if(s->top - s->base == s->maxsize)
{
printf("栈满!\n");
exit(0);
}
*s->top++ = a;
}
void pop(SqStack* s,ElemType *e)
{
if(s->top == s->base)
{
printf("栈已空\n");
return;
}
*e = *--s->top;
}
int StackLen(SqStack s)
{
return (s.top-s.base);
}
int main()
{
char c;
SqStack s;
char str[20];
int i = 0;
double d,e;
printf("以逆波兰表达式输入,数据与运算符间用空格隔开,以#作为结束标志");
init(&s,20);
printf("请输入二进制整数。\n");
scanf("%c",&c);
while( c != '#')
{
while(c >= '0'&&c <= '9') //判断是否为10进制整数
{
str[i++] = c;
str[i] = '\0';
scanf("%c",&c);
if(c == ' ') //空格前的数入栈
{
d = atof(str);
push(&s,d);
i=0;
break;
}
}
switch(c)
{
case '+':
pop(&s,&e);
pop(&s,&d);
push(&s,d+e);
break;
case '-':
pop(&s,&e);
pop(&s,&d);
push(&s,d-e); 注意d和e的顺序
break;
case '*':
pop(&s,&e);
pop(&s,&d);
push(&s,d*e);
break;
case '/':
pop(&s,&e);
pop(&s,&d);
if(e != 0)
{
push(&s,d/e); //注意d和e的顺序
}
else
{
printf("\n除数不能为0!\n");
return -1;
}
break;
}
scanf("%c",&c);
}
pop(&s,&d);
printf("计算结果为:%f\n",d);
return 0;
}