1、北京理工大学 数据结构 实验报告 实验二 简易计算器实验二 简易计算器姓名:任子龙 学号:1120140167 班级:05111451一.需求分析1.程序要求可对一实数算术表达式进行简单的数学运算,可以识别带+、-、*、/、%、(乘方)等等运算符及括号的中缀表达式,从键盘上输入一算术表达式(一般为中缀表达式),计算出表达式的值。2.按照四则运算规则,求表达式的值。一般规则如下:1)先括号内,再括号外。2)先乘方,再乘除,后加减。b.同级运算从左到右顺序执行。3.有良好的提示信息,引导用户在键盘上输入规定的运算指令;如表达式有误,也应给出相应的提示信息。4.建立两个工作栈,分别保存运算符,操作数
2、或运算结果。二.概要设计1.抽象数据类型的定义为实现上述功能,建立两个工作栈;算符为字符型变量,算数为单精度浮点型变量,则需要定义两种数据类型分别存储。typedef struct StackChar char c;structStackChar*next;SC;typedef struct StackFloatfloat f;structStackFloat *next;SF;2.本程序包含两个模块(1)主程序模块主函数只包含了输入输出部分。流程为:首先输入算式,然后调用算符优先算法函数EvaluateExpression(s)进行计算,结果输出;然后循环下去,直到输入OUT指令,退出程序;
3、(2)链栈单元模块实现栈的链式存储的抽象数据类型。各函数之间的调用关系:三.详细设计1.结点类型typedef struct StackChar char c;structStackChar*next;SC;typedef struct StackFloatfloat f;structStackFloat *next;SF;2.子函数(1)算符优先算法的主干函数floatEvaluateExpression(char*e)实现算符优先算法主干的函数。首先判断是算符还是算数,如果是算符,与算符栈栈顶元素进行优先级比较,如果该算符优先级比原栈顶元素优先级高,则进栈,否则进行运算;如果是算数,则入算
4、数栈。(2)进栈出栈函数SC*Push(SC*s,charc);/使算符c进入算符栈SF*Push(SF*s,floatf);/使数值f进入数值栈SC*Pop(SC*s);/使算符栈的栈顶元素出栈SF*Pop(SF*s);/使数值栈的栈顶元素出栈分别实现算符和数值的进栈和出栈操作,由EvaluateExpression函数直接调用。(3)运算函数floatOperate(floata,unsignedchart,floatb);进行运算,a,b为数,t为运算符,进行加减乘除或乘方运算,返回值为运算的结果。(4)类型判断函数StatusIn(charTest,char*TestOp);判断是不是
5、运算符,返回是或不是。(5)优先级判断函数charprecede(charAop,charBop);判断两个算符的优先级,返回或或=。(6)运算符识别函数intReturnOpOrd(charop,char*TestOp);判断是哪个运算符。3.主函数int main()/主函数,用来输入输出和调用子函数 char s128,a4=OUT; 提示信息; k:printf(n请输入计算表达式:); scanf(%s,s); if(strcmp(s,a) printf(n%sb=%gn,s,EvaluateExpression(s);/调用算符优先算法函数 goto k; else exit(0)
6、; 四.调试分析1.为了提高程序的健壮性,在switch语句中加了case为“?”的情况,对其它非法输入也进行考虑;2.对关于栈的基本操作,在编写过程中暴露出问题;2.如何实现按照运算法则进行计算真的特别难,好在老师在课堂上讲过算符优先算法,看到题目并不是很慌;同时也说明了编程时,好的算法意味着成功了一半。五.测试结果1.对给定的测试数据4.5+6.5*1.06=11.39,测试通过;2.对于非法的输入,如2*(1+8*9( ,给出错误提示;3.输入大写OUT,直接退出程序。六附录#include#include#include#includetypedef int Status; /将int
7、定义为自定义数据类型 typedef struct StackChar char c; struct StackChar *next; SC;/存放算符的栈typedef struct StackFloat float f; struct StackFloat *next; SF;/存放数值的栈char OPSET9=+,-,*,/,(,),#,%;unsigned char Prior99=/算符间的优先级表,用于算符优先算法的判断 /+ - * / ( ) # %/*+*/,/*/*/,/*(*/,=,?,?,/*#*/,?,=,/*%*/,;/函数的声明 float EvaluateEx
8、pression(char* e);/实现算符优先算法的函数SC* Push1(SC *s,char c);/使算符c进入算符栈SF* Push2(SF *s,float f);/使数值f进入数值栈SC* Pop1(SC *s);/使算符栈的栈顶元素出栈SF* Pop2(SF *s);/使数值栈的栈顶元素出栈float Operate(float a,unsigned char t, float b); /进行运算,a,b为数,t为运算符Status In(char Test,char* TestOp);/判断是不是运算符,返回是或不是char precede(char Aop,char Bo
9、p);/判断优先级,返回或c!=#) if(!In(*c,OPSET)/In(*c)判断是不是运算符;不是运算符则进栈 Dr0=*c; strcat(TempData,Dr);/字符串连接函数 c+; if (In(*c,OPSET) Data=atof(TempData);/字符串转换函数 OPND=Push2(OPND, Data); strcpy(TempData,0); else switch (precede(OPTR-c,*c)/precede(char a,char b)函数比较下一个字符和栈顶元素的优先级 case :/退栈并将运算结果入栈 theta=OPTR-c;OPTR=
10、Pop1(OPTR); b=OPND-f;OPND=Pop2(OPND); a=OPND-f;OPND=Pop2(OPND); OPND=Push2(OPND,Operate(a,theta,b);break; case ?:/输入非法,报错提示 printf(请输入正确的算术表达式!n);exit(0); return OPND-f; SC* Push1(SC *s,char c)/使算符c进入算符栈 SC *p=(SC*)malloc(sizeof(SC); p-c=c; p-next=s; return p; SF* Push2(SF *s,float f)/使数值f进入数值栈 SF *
11、p=(SF*)malloc(sizeof(SF); p-f=f; p-next=s; return p; SC* Pop1(SC *s)/使算符栈的栈顶元素出栈 SC *q=s; s=s-next; free(q); return s; SF* Pop2(SF *s)/使数值栈的栈顶元素出栈 SF *q=s; s=s-next; free(q); return s; float Operate(float a,unsigned char t, float b)/进行运算,a,b为数,t为运算符 switch(t) case +: return a+b; case -: return a-b;
12、case *: return a*b; case /: return a/b; case : return pow(a,b); case %: int c,d;c=b/1;d=a/1;return d%c; default : return 0; Status In(char Test,char* TestOp)/判断是不是运算符,返回是或不是 int i=0; int flag=0; for(i=0;i或或= return PriorReturnOpOrd(Aop,OPSET)ReturnOpOrd(Bop,OPSET); int ReturnOpOrd(char op,char *Test
13、Op)/判断是哪个运算符 int i=0; for(i=0; i9; i+) if(op =TestOpi) return i; int main()/主函数,用来输入输出和调用子函数 char s128,a4=OUT; printf(*n); printf( 简易计算器n); printf(*nn); printf(使用说明:n); printf(1.输入法为英文输入法;n); printf(2.由于不能区分负号和减号,不支持负数计算;n); printf(3.退出程序请输入大写OUT.n); printf(n); k:printf(n请输入计算表达式:); scanf(%s,s); if(strcmp(s,a) printf(n%sb=%gn,s,EvaluateExpression(s);/调用算符优先算法函数 goto k; else printf(n已退出计算器!);exit(0);
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1