表达式求值时数据结构的基础算法之一,其主要思想就是堆栈的使用。下面将详细的介绍算法的各个部分:
一、算法流程
表达式求值算法主要流程如下:
首先要说明的是后缀表达式,后缀表达式即 不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:(2 + 1) * 3 , 即2 1 + 3 *。转换成后缀表达式的原因是方便及更有条理的计算。
那么又该如何将普通表达式转换成后缀表达式呢?
在转换过程中要用到一个运算符堆栈,用来保存临时运算符。转换判断条件如下:
在转换过程中要注意以下几点:
①、在读到末尾'\0'后要注意把运算符堆栈内的剩余元素依次存入后缀表达式。
②、在读到一个数字后要将后面剩余的数字也依次存入后缀表达式,并且要最后添加#作为各个数字的分隔符。
③、在计算后缀表达式时将读入的数字字符串转换成整数并存入数字堆栈。
④、计算后缀表达式时遇到计算符号则从数字堆栈中退出2个数字,计算出值后再存入数字堆栈。
二、代码
#include<stdio.h> #define MAXSIZE 100 typedef struct stack { int top; char s[MAXSIZE]; }stack; typedef struct numstack { int top; int num[MAXSIZE]; }numstack; void gettop(stack s,char *outch) { *outch=s.s[s.top]; } int IntoStack(stack *st,char in) { if(st->top==MAXSIZE-1)return -1; st->s[(st->top)++]=in; return 0; } int OutStack(stack *st,char *out) { if(st->top==0)return -1; *out=st->s[--(st->top)]; return 0; } int trans(char *exp,char *cal) { char ch,temp; int i=0,j=0; ch=exp[0]; stack st; st.top=0; while(ch!='\0') { switch(ch) { case '(': IntoStack(&st,ch); break; case '+': case '-': while(st.top!=0&&st.s[st.top-1]!='(') { OutStack(&st,&temp); cal[j++]=temp; } IntoStack(&st,ch); break; case '*': case '/': while(st.top!=0&&st.s[st.top-1]!='('&& (st.s[st.top-1]=='*'||st.s[st.top-1]=='/')) { OutStack(&st,&temp); cal[j++]=temp; } IntoStack(&st,ch); break; case ')': while(st.top!=0) { OutStack(&st,&temp); if(temp!='(') cal[j++]=temp; else break; } break; case ' ': break; default : while(ch>='0'&&ch<='9') { cal[j++]=ch; ch=exp[++i]; } i--; cal[j++]='#'; break; } ch=exp[++i]; } while(st.top!=0) { cal[j++]=st.s[--(st.top)]; } cal[j]='\0'; return 0; } int calculate(char exp[]) { int i=0,temp,a,b; numstack numst; numst.top=0; while(exp[i]!='\0') { temp=0; while(exp[i]>='0'&&exp[i]<='9') { temp=temp*10+(exp[i++]-'0'); } if(exp[i]=='#') { i++; numst.num[numst.top++]=temp; } else { b=numst.num[--(numst.top)]; a=numst.num[--(numst.top)]; switch(exp[i++]) { case '+': numst.num[(numst.top)++]=a+b;break; case '-':numst.num[(numst.top)++]=a-b;break; case '*':numst.num[(numst.top)++]=a*b;break; case '/':numst.num[(numst.top)++]=a/b;break; } } } return numst.num[--(numst.top)]; } int main() { char exp[100],cal[200]; while(scanf("%s",exp)) { trans(exp,cal); printf("%d\n",calculate(cal)); } return 0; }