北京理工大学 数据结构 实验报告 实验二简易计算器.docx

上传人:b****6 文档编号:5899068 上传时间:2023-01-02 格式:DOCX 页数:10 大小:118.69KB
下载 相关 举报
北京理工大学 数据结构 实验报告 实验二简易计算器.docx_第1页
第1页 / 共10页
北京理工大学 数据结构 实验报告 实验二简易计算器.docx_第2页
第2页 / 共10页
北京理工大学 数据结构 实验报告 实验二简易计算器.docx_第3页
第3页 / 共10页
北京理工大学 数据结构 实验报告 实验二简易计算器.docx_第4页
第4页 / 共10页
北京理工大学 数据结构 实验报告 实验二简易计算器.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

北京理工大学 数据结构 实验报告 实验二简易计算器.docx

《北京理工大学 数据结构 实验报告 实验二简易计算器.docx》由会员分享,可在线阅读,更多相关《北京理工大学 数据结构 实验报告 实验二简易计算器.docx(10页珍藏版)》请在冰豆网上搜索。

北京理工大学 数据结构 实验报告 实验二简易计算器.docx

北京理工大学数据结构实验报告实验二简易计算器

实验二简易计算器

姓名:

任子龙学号:

1120140167班级:

05111451

一.需求分析

1.程序要求可对一实数算术表达式进行简单的数学运算, 可以识别带+、-、*、/、%、^(乘方)等等运算符及括号的中缀表达式,从键盘上输入一算术表达式(一般为中缀表达式),计算出表达式的值。

 

2.按照四则运算规则,求表达式的值。

一般规则如下:

 1)先括号内,再括号外。

 2)先乘方,再乘除,后加减。

 b. 同级运算从左到右顺序执行。

 

3.有良好的提示信息,引导用户在键盘上输入规定的运算指令;如表达式有误,也应给出相应的提示信息。

 

4.建立两个工作栈,分别保存运算符,操作数或运算结果。

二.概要设计

1.抽象数据类型的定义 

为实现上述功能,建立两个工作栈;算符为字符型变量,算数为单精度浮点型变量,则需要定义两种数据类型分别存储。

typedef struct StackChar{     

char c;  

   struct StackChar *next;   

 }SC;  

typedef struct StackFloat{     

float f;  

   struct StackFloat *next;   

 }SF;  

2.本程序包含两个模块

(1)主程序模块

主函数只包含了输入输出部分。

流程为:

首先输入算式,然后调用算符优先算法函数EvaluateExpression(s)进行计算,结果输出;然后循环下去,直到输入OUT指令,退出程序;

(2)链栈单元模块——实现栈的链式存储的抽象数据类型。

各函数之间的调用关系:

三.详细设计

1.结点类型

typedef struct StackChar{     

char c;  

   struct StackChar *next;   

 }SC;  

typedef struct StackFloat{     

float f;  

   struct StackFloat *next;   

 }SF;

2.子函数

(1)算符优先算法的主干函数float EvaluateExpression(char* e) 

   实现算符优先算法主干的函数。

首先判断是算符还是算数,如果是算符,与算符栈栈顶元素进行优先级比较,如果该算符优先级比原栈顶元素优先级高,则进栈,否则进行运算;如果是算数,则入算数栈。

 

(2)进栈出栈函数 

SC* Push(SC *s,char c);//使算符c进入算符栈      

SF* Push(SF *s,float f);//使数值f进入数值栈   

SC* Pop(SC *s);//使算符栈的栈顶元素出栈   

 SF* Pop(SF *s);//使数值栈的栈顶元素出栈     

分别实现算符和数值的进栈和出栈操作,由EvaluateExpression函数直接调用。

 

(3)运算函数float Operate(float a,unsigned char t, float b);  

    进行运算,a,b为数,t为运算符 ,进行加减乘除或乘方运算,返回值为运算的结果。

 

(4)类型判断函数 Status In(char Test,char* TestOp);     判断是不是运算符 ,返回是或不是。

 

(5)优先级判断函数 char precede(char Aop, char Bop);     判断两个算符的优先级,返回'>'或'<'或'='。

  

(6)运算符识别函数int ReturnOpOrd(char op,char *TestOp);     判断是哪个运算符。

3.主函数

intmain()//主函数,用来输入输出和调用子函数

{

chars[128],a[4]="OUT";

提示信息;

k:

printf("\n请输入计算表达式:

");

scanf("%s",s);

if(strcmp(s,a))

{

printf("\n%s\b=%g\n",s,EvaluateExpression(s));//调用算符优先算法函数

gotok;

}

elseexit(0);

}

四.调试分析

1.为了提高程序的健壮性,在switch语句中加了case为“?

”的情况,对其它非法输入也进行考虑;

2.对关于栈的基本操作,在编写过程中暴露出问题;

2.如何实现按照运算法则进行计算真的特别难,好在老师在课堂上讲过算符优先算法,看到题目并不是很慌;同时也说明了编程时,好的算法意味着成功了一半。

五.测试结果

1.对给定的测试数据4.5+6.5*1.06=11.39,测试通过;

2.对于非法的输入,如2*(1+8*9(,给出错误提示;

3.输入大写OUT,直接退出程序。

六.附录

#include

#include

#include

#include

typedefintStatus;//将int定义为自定义数据类型

typedefstructStackChar{

charc;

structStackChar*next;

}SC;//存放算符的栈

typedefstructStackFloat{

floatf;

structStackFloat*next;

}SF;//存放数值的栈

charOPSET[9]={'+','-','*','/','(',')','#','^','%'};

unsignedcharPrior[9][9]={//算符间的优先级表,用于算符优先算法的判断

//'+''-''*''/''('')''#''^''%'

/*'+'*/'>','>','<','<','<','>','>','<','<',

/*'-'*/'>','>','<','<','<','>','>','<','<',

/*'*'*/'>','>','>','>','<','>','>','<','>',

/*'/'*/'>','>','>','>','<','>','>','<','>',

/*'('*/'<','<','<','<','<','=','?

','<','<',

/*')'*/'>','>','>','>','?

','>','>','>','>',

/*'#'*/'<','<','<','<','<','?

','=','<','<',

/*'^'*/'>','>','>','>','<','>','>','>','>',

/*'%'*/'>','>','>','>','<','>','>','<','>'};

//函数的声明

floatEvaluateExpression(char*e);//实现算符优先算法的函数

SC*Push1(SC*s,charc);//使算符c进入算符栈

SF*Push2(SF*s,floatf);//使数值f进入数值栈

SC*Pop1(SC*s);//使算符栈的栈顶元素出栈

SF*Pop2(SF*s);//使数值栈的栈顶元素出栈

floatOperate(floata,unsignedchart,floatb);//进行运算,a,b为数,t为运算符

StatusIn(charTest,char*TestOp);//判断是不是运算符,返回是或不是

charprecede(charAop,charBop);//判断优先级,返回'>'或'<'或'='

intReturnOpOrd(charop,char*TestOp);//判断是哪个运算符

floatEvaluateExpression(char*e)//算术表达式求值的算符优先算法。

{//设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合。

SC*OPTR=NULL;//算符栈,字符元素

SF*OPND=NULL;//数值栈,实数元素

charTempData[20];

floatData,a,b;

chartheta,*c,x,Dr[]={'#','\0'};

OPTR=Push1(OPTR,'#');

c=strcat(e,Dr);

strcpy(TempData,"\0");

while(*c!

='#'||OPTR->c!

='#')

{

if(!

In(*c,OPSET))//In(*c)判断是不是运算符;不是运算符则进栈

{

Dr[0]=*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(chara,charb)函数比较下一个字符和栈顶元素的优先级

{case'<':

//栈顶元素优先权低

OPTR=Push1(OPTR,*c);

c++;break;

case'=':

//脱括号并接收下一字符

OPTR=Pop1(OPTR);

c++;break;

case'>':

//退栈并将运算结果入栈

theta=OPTR->c;OPTR=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);

}

}

}

returnOPND->f;

}

SC*Push1(SC*s,charc)//使算符c进入算符栈

{

SC*p=(SC*)malloc(sizeof(SC));

p->c=c;

p->next=s;

returnp;

}

SF*Push2(SF*s,floatf)//使数值f进入数值栈

{SF*p=(SF*)malloc(sizeof(SF));

p->f=f;

p->next=s;

returnp;

}

SC*Pop1(SC*s)//使算符栈的栈顶元素出栈

{SC*q=s;

s=s->next;

free(q);

returns;

}

SF*Pop2(SF*s)//使数值栈的栈顶元素出栈

{

SF*q=s;

s=s->next;

free(q);

returns;

}

floatOperate(floata,unsignedchart,floatb)//进行运算,a,b为数,t为运算符

{

switch(t)

{

case'+':

returna+b;

case'-':

returna-b;

case'*':

returna*b;

case'/':

returna/b;

case'^':

returnpow(a,b);

case'%':

{intc,d;c=b/1;d=a/1;returnd%c;}

default:

return0;

}

}

StatusIn(charTest,char*TestOp)//判断是不是运算符,返回是或不是

{

inti=0;

intflag=0;

for(i=0;i<9;i++)

{

if(Test==TestOp[i])

flag=1;

}

returnflag;

}

charprecede(charAop,charBop)//判断优先级,返回'>'或'<'或'='

{

returnPrior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)];

}

intReturnOpOrd(charop,char*TestOp)//判断是哪个运算符

{inti=0;

for(i=0;i<9;i++)

if(op==TestOp[i])

returni;

}

intmain()//主函数,用来输入输出和调用子函数

{

chars[128],a[4]="OUT";

printf("*******************************************\n");

printf("简易计算器\n");

printf("*******************************************\n\n");

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%s\b=%g\n",s,EvaluateExpression(s));//调用算符优先算法函数

gotok;

}

else{printf("\n已退出计算器!

");exit(0);}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 生产经营管理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1