用两种方法实现表达式自动计算_第1页
用两种方法实现表达式自动计算_第2页
用两种方法实现表达式自动计算_第3页
用两种方法实现表达式自动计算_第4页
用两种方法实现表达式自动计算_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、精选优质文档-倾情为你奉上一、设计思想计算算数表达式并求值,可以采取两种算法:1.先将算术表达式转化为后缀表达式,然后对后缀表达式进行计算。2.直接对算术表达式进行计算。下面依次对两种方法进行分析:第一种算法有两步1.先将算数表达式转化为后缀表达式。在计算过程中,第一,要先建立一个存放操作符的栈和一个存放数字的数组。首先对用户输入的表达式进行扫面,如果是数字或者是小数点,直接存入数组。如果是操作符,就判断是否为空或者是否为“(”或者是否它的优先级大于操作符栈顶的优先级,如果是,就入栈,索引后移;如果它的优先级不大于栈顶操作符,栈顶的操作符出栈,进入数组,如此循环,直到栈顶的优先级小于扫描到的操

2、作符的优先级的时候,操作符入栈,索引后移。当遇到标识符0时,扫描结束。数组中存放的就是后缀表达式。2.利用后缀表达式进行计算。得到后缀表达式后,要计算就需要用到数值栈。首先对后缀表达式进行扫描,遇到数字字符,将数字字符转化为浮点类型,放入数值栈中,遇到操作符,就从数值栈中取出两个数,进行计算后将计算结果再放入数值栈中,扫描下一个,最后的计算结果就存到了数值栈中,直接取出数值栈栈顶元素,就是计算的最后结果。第二种算法首先要建立两个栈,一个存放操作符的栈,一个是存放数值的栈。然后开始对用户输入的表达式进行扫描,如果是数值或是小数点,就将其转化为浮点型数据,然后进入数值栈;如果是操作符,当前索引下的

3、操作符的优先级如果不大于栈顶操作符的优先级,就将栈顶操作符取出来,从数值栈中取出两个数值,进行计算,结果存入数值栈。如此循环,直到栈顶操作符的优先级小于当前索引的操作符的优先级是,操作符入栈,然后对下一个字进行扫描。如果是左括号,则不进行优先级的比较,直接入栈。如果是右括号,则从数值栈中取两个操作数,符号栈中取出一个符号,然后进行计算后得数放入数栈中,不断进行此类操作,直到从栈中取出的是左括号为止,左括号丢弃,扫描下一个。扫描结束后,数值栈中存放的数值就是计算产生的结果,最后把数值从数值栈中取出,就是所得的计算结果。二、算法流程图第一种算法:先将表达式转化为后缀表达式,然后计算表达式的值。 1

4、、中缀表达式转化为后缀表达式说明:首先获得算术运算符,对其进行扫面,如果是数字或者是小数点直接进入字符数组。如果是操作符,需要判断它与操作符栈顶操作符的优先级大小来决定是入栈还是栈顶出栈。如果是括号,左括号直接入栈,右括号从栈中找左括号,然后抛弃。扫描结束,字符数组中存放的就是后缀表达式,输出即可。将中缀表达式转化为后缀表达式流程图如下:出栈入数组获取表达式直接入栈不是左括号右括号看栈顶左括号哪种括号优先级不大于栈顶元素栈顶元素出栈,放入字符数组与栈顶比较操作符直接放入字符数组小数点或者数字2、后缀表达式的计算说明:首先获取后缀表达式,对表达式进行扫描,如果是数字转换成相应的浮点型数字,放入数

5、栈,如果是操作符,进行相应的计算。后缀表达式的计算,实现的流程图如下:入栈图1 中缀表达式转化为后缀表达式算法流程图优先级大于栈顶元素如果是括号扫描判断得到后缀表达式扫描判断转换成浮点型,入数栈数字操作符数栈中取两数字计算,结果入栈取出计算结果图2 后缀表达式计算算法流程图第二种算法:直接计算出结果直接计算出结果的算法流程图如下:返回数栈栈顶元素获取计算表达式扫描判断转换成浮点型,入数栈数字与栈顶比较操作符数栈取出两个元素进行计算,结果入数栈直接入栈优先级高优先级低括号类型入栈栈中取出操作符括号左括号右括号是否“(”丢弃是不是数栈取出两个元素进行计算,结果入数栈操作符栈是否空是操作符栈顶元素与

6、数栈取出两个元素进行计算,结果入数栈不是图3 直接进行表达式求值算法流程图说明:首先得到要计算的表达式,并对其进行扫描,遇到的字符是数字,转换成浮点型,入栈。如果是括号,视其左右,判断是入栈或者是丢弃。如果是操作符,视其优先级判断是直接入栈还是进行计算。三、源代码1、先转换成后缀表达式,再进行表达式计算#include<stdio.h>#include<string.h>#include<math.h>#define MAXLENGTH 100 #define EMPTY -1 #define FULL 99typedef struct char op MA

7、XLENGTH;int p ;stack;typedef struct double numMAXLENGTH;int p;number;int Isempty (stack *ps) if (ps->p=EMPTY) return 1; else return 0;int Isfull ( stack *ps)if (ps->p = FULL)return 1;else return 0;int Push ( stack *ps,char ch)if (Isfull(ps)return 0;else ps->p +;ps->opps->p = ch ;retur

8、n 1;char Pop ( stack *ps )if (Isempty(ps)return 0;else return ps->opps->p-;char Top ( stack *ps)if (Isempty(ps)return 0;else return ps->opps->p;int Isemptyn (number *ps) if (ps->p=EMPTY) return 1; else return 0;int Isfulln ( number *ps)if (ps->p = FULL)return 1;else return 0;int Pu

9、shn ( number *ps,double dl)if (Isfulln(ps)return 0;else ps->p +;ps->numps->p = dl ;return 1;double Popn ( number *ps )if (Isemptyn(ps)return 0;else return ps->numps->p-;double Topn ( number *ps)if (Isemptyn(ps)return 0;else return ps->numps->p;int getoplevel(char c)if (c='+&

10、#39;|c='-')return 1;else if (c='*'|c='/'|c='%')return 2;else if (c='(')return 0;else return -1;void init(stack *mystack) mystack->p = EMPTY;void initnum(number *mynum)mynum->p = EMPTY;void calculate(char *mylist,stack *mystack)number mynum;int s=0 ;char

11、mynuMAXLENGTH;int smynu =0;double firstod ,secondod,result;double operand;initnum (&mynum);while(mylists!='0')if (mylists='+'|mylists='-'|mylists='*'|mylists='/'|mylists='%'|mylists=' ')switch(mylists)case '+':firstod = Popn(&my

12、num);secondod = Popn(&mynum);result = secondod + firstod;Pushn(&mynum,result);break;case '-':firstod = Popn(&mynum);secondod = Popn(&mynum);result = secondod - firstod;Pushn(&mynum,result);break;case '*':firstod = Popn(&mynum);secondod = Popn(&mynum);resul

13、t = secondod * firstod;Pushn(&mynum,result);break;case '/':firstod = Popn(&mynum);secondod = Popn(&mynum);if(firstod =0)printf("0 can not be dividorn ");return;result = secondod / firstod;Pushn(&mynum,result);break;case '%':firstod = Popn(&mynum);secondo

14、d = Popn(&mynum);result = (double)(int)secondod % (int)firstod);Pushn(&mynum,result);break;case ' ':break;s +;elsewhile (mylists<='9'&&mylists>='0'|mylists='.')mynusmynu = mylists;s +;smynu +;mynusmynu = '0'operand = atof(mynu);Pushn(&

15、;mynum,operand);smynu =0;result = Popn(&mynum);printf("结果是:");printf("%f n",result);void getexpression (char *myexp,stack mystack,char *mylist)int i =0;int s=0;int slist=0; while(myexps!='0') if(myexps<='9'&&myexps>='0'|myexps='.'

16、) while(myexps<='9'&&myexps>='0'|myexps='.') mylistslist = myexp s; s+; slist +; mylistslist=' ' slist+; else if (Isempty(&mystack)|myexps='(') Push(&mystack,myexps); s +; else if (myexps =')') while(Top(&mystack)!='('

17、) mylistslist = Pop(&mystack); slist +; mylistslist=' ' slist+; Pop(&mystack); s+; else if (getoplevel(myexps)>getoplevel(Top(&mystack) Push(&mystack,myexps); s+; else while(getoplevel(myexps)<=getoplevel(Top(&mystack) mylistslist = Pop(&mystack); slist +; mylis

18、tslist=' ' slist+; while(!Isempty(&mystack) mylistslist = Pop(&mystack); slist +; mylistslist=' ' slist+; mylistslist = '0' printf("后缀表达式为: n"); printf("%s",mylist); printf("n"); calculate(mylist,&mystack);void main()char myexp MAXLEN

19、GTH;stack mystack;char mylistMAXLENGTH ;printf("请输入:n");gets(myexp);init(&mystack);getexpression(myexp,mystack,mylist); getch();2、 用直接计算表达式值#include<stdio.h>#include<math.h>#define MAXLENGTH 100 #define EMPTY -1 #define FULL 99 typedef struct char op MAXLENGTH; int p ;stack

20、;typedef struct double numMAXLENGTH;int p;number;int Isempty (stack *ps) if (ps->p=EMPTY) return 1; else return 0;int Isfull ( stack *ps)if (ps->p = FULL)return 1;else return 0;int Push ( stack *ps,char ch)if (Isfull(ps)return 0;else ps->p +;ps->opps->p = ch ;return 1;char Pop ( stack

21、 *ps )if (Isempty(ps)return 0;else return ps->opps->p-;char Top ( stack *ps)if (Isempty(ps)return 0;else return ps->opps->p;int Isemptyn (number *ps) if (ps->p=EMPTY) return 1; else return 0;int Isfulln ( number *ps)if (ps->p = FULL)return 1;else return 0;int Pushn ( number *ps,dou

22、ble dl)if (Isfulln(ps)return 0;else ps->p +;ps->numps->p = dl ;return 1;double Popn ( number *ps )if (Isemptyn(ps)return 0;else return ps->numps->p-;double Topn ( number *ps)if (Isemptyn(ps)return 0;else return ps->numps->p;int getoplevel(char c)if (c='+'|c='-')r

23、eturn 1;else if (c='*'|c='/'|c='%')return 2;else if (c='(')return 0;else return -1;void init(stack *mystack) mystack->p = EMPTY;void initnum(number *mynum)mynum->p = EMPTY;void calculate(char *myexp)stack mystack;number numstack;char mylistMAXLENGTH;int index =0

24、;int indexlist=0;double od1 ,od2;double result,operand ;init(&mystack);initnum(&numstack);while(myexpindex!='0')/if (myexpindex<='9'&&myexpindex>='0'|myexpindex='.')while(myexpindex<='9'&&myexpindex>='0'|myexpindex=&

25、#39;.')mylistindexlist = myexpindex;index +;indexlist +;mylistindexlist = '0'operand = atof(mylist);Pushn(&numstack,operand);indexlist = 0;else if(Isempty(&mystack)|myexpindex='('|getoplevel(myexpindex)>getoplevel(Top(&mystack)Push(&mystack,myexpindex);index +;

26、else if (myexpindex=')')while(Top(&mystack)!='(') od1 = Popn(&numstack);od2 = Popn(&numstack);switch(Top(&mystack)case '+': Pushn(&numstack,od2 + od1);break;case '-':Pushn(&numstack,od2 - od1);break;case '*':Pushn(&numstack,od2 * od

27、1);break;case '/':if(od1 =0)printf("0 can not be divisor n");return ;Pushn(&numstack,od2 / od1);break;case '%':Pushn(&numstack,(double)(int)od2 % (int)od1);break; Pop(&mystack); index +; Pop(&mystack); elsewhile(getoplevel(myexpindex)<=getoplevel(Top(&

28、;mystack)od1 = Popn(&numstack);od2 = Popn(&numstack);switch(Top(&mystack)case '+':Pushn(&numstack,od2 + od1);break;case '-':Pushn(&numstack,od2 - od1);break;case '*':Pushn(&numstack,od2 * od1);break;case '/':if(od1 =0) printf("0 不能做除数!请重新输

29、入.n");return ;Pushn(&numstack,od2 / od1);break;case '%':Pushn(&numstack,(double)(int)od2 % (int)od1);break;Pop(&mystack);Push(&mystack,myexpindex);index +;while (!Isempty(&mystack)od1 = Popn(&numstack);od2 = Popn(&numstack);switch(Top(&mystack)case '+

30、':Pushn(&numstack,od2 + od1);break;case '-':Pushn(&numstack,od2 - od1);break;case '*':Pushn(&numstack,od2 * od1);break;case '/':if(od1 =0) printf("0 can not be divisor n");return ;Pushn(&numstack,od2 / od1);break;case '%':Pushn(&numst

31、ack,(double)(int)od2 % (int)od1);break;Pop(&mystack);result = Topn(&numstack);printf("The result is:n");printf("%f n",result);void main()char myexpMAXLENGTH;printf("Please input the expression:n");gets(myexp);calculate(myexp); getch();四、运行结果第一种算法程序运行结果图:正确输入表达式,

32、程序运行结果如图:图5 正确表达式运行结果图第二种算法程序运行结果图:正确输入表达式,程序运行结果如图:图6 正确表达式运行结果图五、遇到的问题及解决这部分我主要遇到了如下两个问题,其内容与解决方法如下所列:一要把后缀表达式放到了字符数组中,是如何将后缀表达式中的数字字符转换成真正的数字?如果是单个的数字,可以进行强制转换,但是数字不总都是单个的,我们要计算的数字往往是多位的如:12,或者带有小数点如:1.2,那么怎么将其转换成真正的浮点型的数字呢?解决方案:分析问题,我们知道重点是如何将多位的数字字符转换成浮点型数字,同时也知道多位的数字字符是存储地址是连续的,于是根据这个特点,我查阅了一下C语言库函数,果然真的有符合条件的库函数atof();首先atof()函数在“math.h”头文件下,引用“math.h”就可以使用atof()函数直接将地址连续的多位数字字符转换成相应的浮点型数字。有了思路,我想到将字符数组中的数字按分隔符依次转移到另一个字符数组中,并利用atof()函数将其转换成相应的数字,但是

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论