1、算术表达式求值演示一、需求分析(1) 输入的形式:语法正确的、不含变量的字符序列形式的整数表达式输入值的范围:整数的范围是(215-l)(215-1)运算符:+,-,*,/,(,)表达式结束运算符 #(2) 输出的形式:范围是(215-l)(215-1)的整数(3) 程序所能达到的功能:实现对算术四则混合运算表达式的求值;程序执行命令包括:1) Calculate 计算表达式的值2) Exit 退出(4) 测试数据1) 82) 2-2-2-3;3) 4+26/12-2*7;4) 18-3*7-15/6;5) 2*(6+2*(3+6*(6+6);演示程序以用户与计算机交互方式执行,即在计算机终端
2、上显示提示信息之后,由用户在键盘上输入演示程序中规定的运算命令;相应的输入数据(滤去输入中的 非法字符)和运算结果显示在其后。二、概要设计(1) 为实现上述程序功能需要的抽象数据类型:1) 栈的抽象数据类型:ADT Stack数据对象:D= |ai|aielemset, i=1,2, ,n,n0 数据关系:R1=| ai-1,aiD, i=2,n 基本操作:InitStack() 操作结果:构造一个空栈。GetTop(S,&e)初始条件:栈S已存在且非空。操作结果:用e返回S的栈顶元素。Push(&S,e) 初始条件:栈S已存在。 操作结果:插入元素e为新的栈顶元素。Pop(&S,&e)初始条
3、件:栈S已存在且非空。操作结果:删除S的栈顶元素,并且用e返回其值。ADT Stack2) 系统中子程序及功能要求:Precede(char c1,char c2):比较两个字符的优先级,并返回比较结果。Operate(SElemType a,char op,SElemType b):函数进行四则运算,并返回运算结果。judge(char op):判断是否为运算符。EvaluateExpression():进行四则混合运算,并返回运算结果。(2) 本次程序设计中一共有三个模块,一个是由主函数构成的模块,一个是由各个子功能函数构成的栈模块,第三个是由运算等函数构成的运算模块。(3) 主模块可以对
4、子模块中的函数进行调用,但子模块不能对主模块中的内容进行调用;子模块中的函数可相互调用。具体函数调用关系如下:main 调用 EvaluateExpression() EvaluateExpression() 调用 Precede、Operate、judge、InitStack()、 GetTop、 Push、Pop。三、详细设计(1) 程序流程图:(2) 元素类型、结点类型和指针类型typedef int Status;typedef int SElemType; /元素类型typedef structSElemType *base;SElemType *top;int stacksize;
5、SqStack; /结点类型和指针类型(3) 栈的基本操作定义如下:Status InitStack(SqStack *S);/构造一个空栈SStatus GetTop(SqStack S)/若栈不空,则返回栈顶元素,否则返回ERRORStatus Push(SqStack *S,SElemType e);/插入e为新的栈顶元素Status Pop(SqStack *S,SElemType *e);/若栈不空,则删除S的栈顶元素,用e返回其值,返回OK,否则返回ERROR(4) 系统中子程序的基本操作定义:Char Precede(char c1,char c2);/进行运算符的优先级比较,并
6、返回比较结果。SElemType Operate(SElemType a,char op,SElemType b);/进行两个整数数的四则运算,并返回运算结果。Status judge(char op) /判断是否为运算符。SElemType EvaluateExpression()/进行四则混合运算,并返回运算结果。(5) 部分基本操作的源程序如下:Status Push(SqStack *S,SElemType e)*(S-top)+=e; return OK; /插入元素e为新的栈顶元素Status Pop(SqStack *S,SElemType *e)if(S-top=S-base)
7、return ERROR; /若栈为空,返回ERROR*e=*(-(S-top); return OK; /栈不为空,删除S的栈顶元素,用e返回其值,并返回OKchar Precede(char a,char b)/根据课本P53,表3-1算符间优先关系编写程序实现算符间的优先级比较SElemType r;switch(a)case+:case-: /+,-运算符优先级相同,故放在一起进行比较if(b=*|b=/|b=()r=;break;case*: /*,/运算符优先级相同,故放在一起进行比较case/:if(b=() r=;break;case(:if(b=#) printf(nLogi
8、c expression error!There is no rightbracket!);return(0) ; /逻辑错误,只有左括号,缺少右括号else if(b=)r=;else r=;break;case#:if(b=)printf(nLogic expression error!There is no leftbracket!); return(0) ; /逻辑错误,只有右括号,缺少左括号 else if(b=#)r=;else r=0&c=9)sum=(sum*10+(c-0);c=getchar();Push(&OPND,sum); /不是运算符进栈sum=0;elseswit
9、ch(Precede(GetTop(OPTR)+0),c) case: /栈顶元素优先级高,退栈并将运算结果进栈 Pop(&OPTR,&theta);Pop(&OPND,&b); Pop(&OPND,&a);e=Operate(a,(theta+0),b); Push(&OPND,e);break;case0:Push(&OPND,0);c=#; /逻辑错误,0进栈 ,并结束运算break; return (GetTop(OPND); 四、调试分析(1) 在调试过程中遇到的两大问题:1)如何进行超过一位的数的存储原因分析:按照预想的想法,对表达式进行实际操作时发现,当输入超过一位的数时,在程序的运行过程中,只进行了数的最低位的运算:例如1+15#,由于系统将15进行两个字符处理后仍按两个字符进行进栈存储,使得实际运行结果为6,显然是错误的解决方案:对操作数的进栈存储程序进行优化,使其能将多位数视为单个字 符进行进栈存储具体程序由原来的if(!judge(c) Push(&OPND,sum); c=getchar(); 优化如下:if(!judge(c) while(c
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1