codeup 1743: 算法3-4:表达式求值

来源:互联网 发布:免费源码分享 编辑:程序博客网 时间:2024/06/07 00:50

1743: 算法3-4:表达式求值

题目描述

算数四则运算的规则是1)先乘除,后加减;2)从左算到右;3)先括号内,后括号外。
由此,算式4+2*3-10/5的计算顺序为4+2*3-10/5=4+6-10/5=4+6-2=8。
给定一个以“#”作为结束符的算式,求出算式的结果。
给出严蔚敏《数据结构(C语言)》中的一段算法描述以作参考:
图1:表达式求值算法
图2:表达式求值算法(续)

3:表达式求值算法(续)

输入

以“#”结尾的表达式,运算数为正整数。每个表达式占一行。

输出

输出表达式运算的结果。

样例输入

4+2*3-10/5#3*(7-2)#2*3/2#

样例输出

8153

置运算符栈为空栈,表达式的起始符'#'为栈底元素

依次读入表达式的每个字符,若是操作数则进OPND栈,若是运算符O则和OPTR栈的栈顶元素比较优先权后进行相应操作,直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为'#').
#include<stdio.h>#include<string.h>#include<stdlib.h>#define N 1000+10#define STACK_INIT_SIZE 100#define STACKINCREMENT 10#define OK 1#define OVERFLOW 0#define ERROR 0char str[N];typedef  int Status;typedef  int SElemType;typedef struct{SElemType *base;SElemType *top;int stacksize;}SqStack;unsigned char prior[7][7] = {{'>','>','<','<','<','>','>'},{'>','>','<','<','<','>','>'},{'>','>','>','>','<','>','>'},{'>','>','>','>','<','>','>'},{'<','<','<','<','<','=',' '},{'<','<','<','<','<',' ','>'},{'<','<','<','<','<',' ','='}};char OPSET[7] = {'+','-','*','/','(',')','#'};Status InitStack(SqStack *s)//初始化栈 {s->base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!s->base)exit(OVERFLOW);s->top = s->base ;s->stacksize = STACK_INIT_SIZE;return OK;}Status Push(SqStack *s,SElemType c)//入栈 {if((s->top - s->base ) >= s->stacksize ){s->base = (SElemType*)realloc(s->base ,(s->stacksize +STACKINCREMENT)*sizeof(SElemType));if(!s->base )exit(OVERFLOW);s->stacksize += STACKINCREMENT;}*(s->top)++ = c;return OK;}Status GetTop(SqStack *s)//取栈顶元素 {SElemType e;if(s->base == s->top )return ERROR;e = *(s->top-1)    ;return e;}Status In(char c,char str[])//判断是否为运算符 {int i = 0;while(c != str[i]){i++;}if(i < 7)return OK;return ERROR;}void  Strcat(char *str1,char *str2)//字符串连接函数,把字符串str2连接到str1后 {int i = 0, j = 0;while(str1[i]!='\0'){i++;}while(str2[j]!='\0'){str1[i++] = str2[j++];}str1[i] = '\0';} Status Atoi(char *c)//把字符串转为数字 {int data= 0,d = 0;int i = 0;while(c[i]!='\0'){data = data*10 + c[i]-'0';i++;}return data;} Status precede(int a,char b)//判断优先级函数 {int i = 0,j = 0;while(OPSET[i] != a){i++;}while(OPSET[j] != b){j++;}return prior[i][j];}Status Pop(SqStack *s)//脱括号函数 {int e;if(s->base == s->top )return ERROR;e = *--(s->top);return e;}Status Opereta(int a,int b,int c)//运算函数 {switch(b){case '+':return a+c;case '-':return a-c;case '*':return a*c;case '/':return a/c;} }int EvaluateExpression(char *MyExpression)//算法3.4 {//算术表达式求值的算符优先算法。//设OPTR和OPND分别为运算符栈和运算数栈SqStack OPTR;//运算符栈,字符元素 SqStack OPND;//运算数栈,实数元素 char TempData[20];int data,a,b;char *c,Dr[2],e;int theta;InitStack(&OPTR);Push(&OPTR,'#');InitStack(&OPND);c = MyExpression;TempData[0] = '\0';while(*c != '#'|| GetTop(&OPTR) != '#'){if(!In(*c,OPSET))//不是运算符则进栈 {Dr[0] = *c;Dr[1] = '\0';Strcat(TempData,Dr);c++; if(In(*c,OPSET))//是运算符时 {data = Atoi(TempData);Push(&OPND,data);TempData[0] = '\0';}}else{switch(precede(GetTop(&OPTR),*c)){case '<':Push(&OPTR,*c);c++;break;case '=':Pop(&OPTR);c++;break;case '>':a = Pop(&OPND);b = Pop(&OPND);theta = Pop(&OPTR);Push(&OPND,Opereta(b,theta,a));break;}}}return GetTop(&OPND);}int main(){while(scanf("%s",str)!=EOF){printf("%d\n",EvaluateExpression(str));}return 0; } 



原创粉丝点击