数据结构课程设计_表达式求值问题
数据结构表达式求值
数据结构表达式求值数据结构表达式求值=================1:引言---------本文档旨在介绍数据结构中的表达式求值问题。
首先会讨论表达式的定义和基本概念,然后介绍不同类型的表达式,并详细阐述它们的求值过程。
最后,本文还会给出一些例子和实用技巧,供读者参考。
2:表达式的定义和基本概念-------------------------表达式是由操作数、操作符和括号组成的数学式子。
它们可以用来表示数学运算、逻辑判断等。
在表达式中,操作数是指参与运算的数值或变量,操作符是指进行运算的符号,括号用于控制运算的优先级和顺序。
3:前缀表达式的求值------------------前缀表达式是一种将操作符放在操作数前面的表达式写法。
求解前缀表达式的过程可以通过使用栈来实现。
4:后缀表达式的求值------------------后缀表达式是一种将操作符放在操作数后面的表达式写法。
求解后缀表达式的过程也可以通过使用栈来实现。
5:中缀表达式的求值------------------中缀表达式是我们常见的数学表达式写法,操作符位于操作数中间。
求解中缀表达式的过程可以通过将中缀表达式转换为后缀表达式来简化。
6:表达式求值的实例-----------------本节将通过一些实例来演示表达式求值的过程,包括前缀表达式、后缀表达式和中缀表达式的求解方法。
7:实用技巧和注意事项-------------------本节将介绍一些实用的技巧和注意事项,可以帮助读者更好地理解和应用表达式求值的方法。
8:附件-------本文档不需要附加内容。
9:法律名词及注释----------------本文档中涉及的法律名词和相关注释如下:- 操作数(operand):参与运算的数值或变量。
- 操作符(operator):进行运算的符号。
- 表达式(expression):由操作数、操作符和括号组成的数学式子。
10:结束语---------本文档详细介绍了数据结构中的表达式求值问题,包括前缀表达式、后缀表达式和中缀表达式的求解方法。
数据结构表达式求值实验报告
竭诚为您提供优质文档/双击可除数据结构表达式求值实验报告篇一:数据结构实验二——算术表达式求值实验报告《数据结构与数据库》实验报告实验题目算术表达式求值学院:化学与材料科学学院专业班级:09级材料科学与工程系pb0920603姓学邮名:李维谷号:pb09206285箱:指导教师:贾伯琪实验时间:20XX年10月10日一、需要分析问题描述:表达式计算是实现程序设计语言的基本问题之一,它的实现是栈的应用的一个典型例子。
设计一个程序,演示通过将数学表达式字符串转化为后缀表达式,并通过后缀表达式结合栈的应用实现对算术表达式进行四则混合运算。
问题分析:在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。
因而在程序设计时,借助栈实现。
设置运算符栈(字符型)和运算数栈(浮点型)辅助分析算符优先关系。
在读入表达式的字符序列的同时完成运算符和运算数的识别处理,然后进行运算数的数值转换在进行四则运算。
在运算之后输出正确运算结果,输入表达式后演示在求值中运算数栈内的栈顶数据变化过程,最后得到运算结果。
算法规定:输入形式:一个(:数据结构表达式求值实验报告)算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)。
为使实验更完善,允许操作数为实数,操作符为(、)、.(表示小数点)、+、-、*、/、^(表示乘方),用#表示结束。
输出形式:演示表达式运算的中间结果和整个表达式的最终结果,以浮点型输出。
程序功能:对实数内的加减乘除乘方运算能正确的运算出结果,并能正确对错误输入和无定义的运算报错,能连续测试多组数据。
测试数据:正确输入:12*(3.6/3+4^2-1)#输出结果:194.4无定义运算:12*(3.6/(2^2-4)+1)#输出结果:表达式出错,除数为0,无意义错误输入:12+s#输出结果:eRRoR!二、概要设计拟采用两种类型的展分别对操作数和操作符进行操作。
数据结构-表达式求值
数据结构:线性结构—栈实现表达式求值一.问题分析利用栈这种数据结构存储数字和运算符,并实现表达式求值。
为实现按运算符优先顺序进行计算,需要在执行程序的过程中对运算符的优先顺序做出判断。
利用栈先进后出的特点,同时保证优先级最高的运算符始终在栈顶。
当栈顶元素优先级低于读入的运算符时,将该栈顶运算符推出。
这就保证了优先级高的运算符先计算。
二.数据结构—栈1.优先关系表:prior[7][7]={// +-*/()#'>','>','<','<','<','>','>','>','>','<','<','<','>','>','>','>','>','>','<','>','>','>','>','>','>','<','>','>','<','<','<','<','<','=',' ','>','>','<','>',' ','>','>','<','<','<','<','<',' ','='};将关系表直接用字符型的二维数组存储。
数据结构课程设计报告-表达式求值
《数据结构》课程设计利用栈求表达式的值班级: 2学号: 100171021330姓名:吴迪指导老师:王方利用栈求表达式的值1、设计思路这个程序的关键是对数字与运算符的判断和运算符优先级的判断,以及出栈的运算。
建立两个栈,分别存储数字与运算符,栈1存运算符,栈2存数字。
依次读取表达式的字符串,先判断是数字还是运算符,如果是数字不能马上压入栈2,因为可能是大于10的数字,应该继续循环,如果还是数字,则利用计算保存数值,直到指到运算符时停止,将计算后的数字压入栈2。
压入运算符之前先将要压入的与栈顶的运算符优先级相比较,如果栈顶是‘(’而当前不是‘)’,则不需比较优先级,直接压入;如果栈顶是‘(’,当前是‘)’,则抵消(弹出‘(’,指向表达式下一个字符);若当前的运算符优先级大于栈顶的,则压入;若当前的运算符优先级小于栈內时,弹出栈顶的运算符,同时弹出两组数字,经过运算符的运算后再重新压到栈内。
为了方便判断运算结束,在存储运算符之前先将‘#’压入栈1中,在输入表达式时以‚#‛结束,所以可以以运算符==‘#’并且栈1顶==‘#’来结束运算,弹出栈2的数值,即为表达式求值的最终结果。
上述操作的算法步骤:(1)初始化算符S1,数字栈S2;,将‘#’压入算符栈S1中。
(2)读表达式字符=>w。
(3)当栈顶为‘#’并且w也是‘#’时结束;否则循环做下列步骤:(3-1)如果w是数字,存储到m,再经过计算存储到num中。
m=w-‘0’;num=num*pow(10,n)+m;n++;读下一个字符=>w,如果是运算符,则跳出循环;转3-2。
(3-2)w若是运算符,则:(3-2-1)如果栈顶为‘(’并且w为‘)’则‘(’出栈,读下一个字符=>w;转(3)。
(3-2-2)如果栈顶为‘(’或者栈顶优先级小于w优先级,则w入栈,读下一个字符=>w;转(3)。
否则:从算符栈中出栈,并从数字栈中弹出两组数字进行运算,将结果重新压入数字栈,转(3)。
数据结构课程设计--表达式求值问题
课程设计(论文)题目名称表达式求值问题课程名称数据结构课程设计学生姓名 XXX学号xxxxxxxxx系、专业信息工程系、信息工程类指导教师 xxxxxx2010年 1 月 3 日目录1 问题描述 (2)2 需求分析 (2)3 概要设计 (2)3.1抽象数据类型定义 (2)3.2模块划分 (3)4 详细设计 (4)4.1数据类型的定义 (4)4.2主要模块的算法描述 (4)5 测试分析 (7)5.1程序运行结果 (7)5.2程序调试与体会 (8)6 课程设计总结 (8)参考文献 (8)附录(源程序清单) (9)1 问题描述编写一个表达式求值程序,使输入一个四则运算表达式后,能够返回正确的结果。
该表达式由数字0~9、+、-、*、/、括号组成,且表达式必须正确无误。
程序的编写可用到栈或队列的基本算法,求出该表达式的值,并分析算法的时间复杂度和运算的结果。
2 需求分析(1)为实现算符优先算法,可以使用两个工作栈。
一个称做OPTR,用以寄存运算符;另一个称做OPND;用以寄存操作数或运算结果。
算法的基本思想是:①首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;②依次读入表达式中每个字符,若是操作数则OPND栈,若是运算符,则和OPTR栈的栈顶运算符比较优先权后做相应操作,直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为"#")。
(2)该程序实现表达式的求值问题:从键盘读入一个合法的算术表达式,利用算符优先关系,实现对算术四则混合运算的求值,输出正确的结果。
3 概要设计3.1抽象数据类型定义设定栈抽象数据类型的定义采用两个栈的入栈与出栈的操作来进行“运算符和操作数的配对”。
程序中主要用到以下抽象数据类型:1)ADT Stack {数据对象:D={ ai | ai∈ElemSet, i=2,...,n,n≥0 }数据关系:R1={ <ai-1, ai >| ai-1, ai∈D, i=2,...,n }约定an端为栈顶,a1端为栈底。
数据结构课程设计-表达式求值【完整版】
XXXXXX大学《数据结构》课程设计报告班级:学号:姓名:指导老师:目录一算术表达式求值一、需求分析二、程序得主要功能三、程序运行平台四、数据结构五、算法及时间复杂度六、测试用例七、程序源代码二感想体会与总结算术表达式求值一、需求分析一个算术表达式就是由操作数(operand)、运算符(operator)与界限符(delimiter)组成得。
假设操作数就是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号与表达式起始、结束符“#”,如:#(7+15)*(23—28/4)#。
引入表达式起始、结束符就是为了方便.编程利用“算符优先法”求算术表达式得值.二、程序得主要功能(1)从键盘读入一个合法得算术表达式,输出正确得结果。
(2)显示输入序列与栈得变化过程。
三、程序运行平台Visual C++6、0版本四、数据结构本程序得数据结构为栈。
(1)运算符栈部分:struct SqStack //定义栈{char *base; //栈底指针char *top; //栈顶指针intstacksize; //栈得长度};intInitStack (SqStack &s) //建立一个空栈S{if (!(s、base= (char *)malloc(50*sizeof(char))))exit(0);s、top=s、base;s、stacksize=50;return OK;}char GetTop(SqStack s,char &e) //运算符取栈顶元素{if (s、top==s、base) //栈为空得时候返回ERROR{ﻩ printf("运算符栈为空!\n");ﻩ return ERROR;}elsee=*(s、top-1); //栈不为空得时候用e做返回值,返回S得栈顶元素,并返回OK returnOK;}int Push(SqStack&s,char e) //运算符入栈{if (s、top—s、base >= s、stacksize)ﻩ{printf("运算符栈满!\n");ﻩs、base=(char*)realloc(s、base,(s、stacksize+5)*sizeof(char));//栈满得时候,追加5个存储空间if(!s、base)exit (OVERFLOW);s、top=s、base+s、stacksize;s、stacksize+=5;}ﻩ*(s、top)++=e;//把e入栈ﻩreturn OK;}int Pop(SqStack &s,char &e) //运算符出栈{if (s、top==s、base) //栈为空栈得时候,返回ERROR{printf("运算符栈为空!\n”);ﻩ return ERROR;}else{ﻩﻩe=*-—s、top;//栈不为空得时候用e做返回值,删除S得栈顶元素,并返回OK return OK;}}int StackTraverse(SqStack&s)//运算符栈得遍历{ﻩchar *t;ﻩt=s、base;ﻩif (s、top==s、base){ﻩ printf(”运算符栈为空!\n”); //栈为空栈得时候返回ERRORreturn ERROR;}while(t!=s、top){ﻩﻩprintf(" %c",*t); //栈不为空得时候依次取出栈内元素t++;ﻩ}return ERROR;}(2)数字栈部分:struct SqStackn//定义数栈{int *base; //栈底指针int*top; //栈顶指针int stacksize; //栈得长度};intInitStackn (SqStackn &s) //建立一个空栈S{s、base=(int*)malloc(50*sizeof(int));if(!s、base)exit(OVERFLOW);//存储分配失败s、top=s、base;s、stacksize=50;return OK;}int GetTopn(SqStackn s,int&e) //数栈取栈顶元素{if(s、top==s、base){printf("运算数栈为空!\n");//栈为空得时候返回ERRORﻩ return ERROR;}elseﻩe=*(s、top-1);//栈不为空得时候,用e作返回值,返回S得栈顶元素,并返回OKreturnOK;}int Pushn(SqStackn &s,int e) //数栈入栈{if(s、top—s、base>=s、stacksize){ﻩﻩprintf("运算数栈满!\n");//栈满得时候,追加5个存储空间ﻩs、base=(int*)realloc (s、base,(s、stacksize+5)*sizeof(int));if(!s、base) exit (OVERFLOW);ﻩs、top=s、base+s、stacksize;//插入元素e为新得栈顶元素s、stacksize+=5;}*(s、top)++=e; //栈顶指针变化returnOK;}int Popn(SqStackn &s,int &e)//数栈出栈{ﻩif (s、top==s、base){ﻩ printf("运算符栈为空!\n");//栈为空栈得视时候,返回ERRORﻩ return ERROR;ﻩ}else{ﻩﻩe=*—-s、top;//栈不空得时候,则删除S得栈顶元素,用e返回其值,并返回OK ﻩreturnOK;}}int StackTraversen(SqStackn &s)//数栈遍历{ﻩint*t;ﻩt=s、base ;ﻩif(s、top==s、base)ﻩ{printf("运算数栈为空!\n”);//栈为空栈得时候返回ERRORﻩ return ERROR;ﻩ}ﻩwhile(t!=s、top)ﻩ{printf(” %d”,*t); //栈不为空得时候依次输出t++;}return ERROR;}五、算法及时间复杂度1、算法:建立两个不同类型得空栈,先把一个‘#’压入运算符栈。
数据结构课程设计四则运算表达式求值(C语言版)
数据结构课程设计四则运算表达式求值(C语⾔版) 明⼈不说暗话,直接上,输⼊提取码z3fy即可下载。
⽂件中包含程序,程序运⾏⽂件,设计报告和测试样例,应有尽有,欢迎⼩伙伴们在中下载使⽤。
本课程设计为四则运算表达式求值,⽤于带⼩括号的⼀定范围内正负数的四则运算标准(中缀)表达式的求值。
注意事项:1、请保证输⼊的四则表达式的合法性。
输⼊的中缀表达式中只能含有英⽂符号“+”、“-”、“*”、“/”、“(”、“)”、“=”、数字“0”到“9”以及⼩数点“.”,输⼊“=”表⽰输⼊结束。
例如9+(3-1)*3.567+10/2=,特别是请勿输⼊多余空格和中⽂左右括号。
2、输⼊的中缀表达式默认限定长度是1001,可根据具体情况调整字符串数组的长度。
3、请保证输⼊的操作数在double数据类型范围内,单个数字有效数字长度不可超过15位。
本课程设计中操作数是C语⾔中的双精度浮点数类型。
4、本课程设计中的运算数可以是负数,另外如果是正数可直接省略“+”号(也可带“+”号)。
下⾯的程序正常运⾏需要在上⾯的百度⽹盘中下载相应⽂件,否则⽆法正常使⽤哦。
1/*本程序为四则运算表达式求值系统,⽤于计算带⼩括号的四则运算表达式求值。
2具体算法:3先将字符串处理成操作单元(操作数或操作符),再利⽤栈根据四则运算4的运算法则进⾏计算,最后得出结果。
*/56 #include<stdio.h>7 #include<ctype.h>8 #include<stdlib.h>9 #include<string.h>10 #include<stdlib.h>11 #include<ctype.h>1213const int Expmax_length = 1001;//表达式最⼤长度,可根据适当情况调整14struct Ope_unit15 {//定义操作单元16int flag;//=1表⽰是操作数 =0表⽰是操作符 -1表⽰符号单元17char oper;//操作符18double real;//操作数,为双精度浮点数19 };2021void Display();//菜单22void Instru(); //使⽤说明23int Check(char Exp_arry[]);24void Evalua(); //先调⽤Conver操作单元化,再调⽤Calculate函数计算结果并输出25int Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[]);//将字符串处理成操作单元26int Isoper(char ch);//判断合法字符(+ - * / ( ) =)27int Ope_Compar(char ope1,char ope2);//操作符运算优先级⽐较28double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag);//⽤栈计算表达式结果29double Four_arithm(double x,double y,char oper);//四则运算3031int main()32 {33int select;34while(1)35 {36 Display();37 printf("请输⼊欲执⾏功能对应的数字:");38 scanf("%d",&select);39 printf("\n");40switch(select)41 {42case1: Evalua(); break;43case2: Instru(); break;44case0: return0;45default : printf("⽆该数字对应的功能,请重新输⼊\n");46 system("pause");47 }48 }49return0;50 }5152int Check(char Exp_arry[])53 {//检查是否有⾮法字符,返回1表⽰不合法,0表⽰合法54int Explength=strlen(Exp_arry),i;55for(i=0;i<Explength;i++)56 {57if(!Isoper(Exp_arry[i]) && Exp_arry[i] != '.' && !isdigit(Exp_arry[i]))58return1;59if(isdigit(Exp_arry[i]))60 {61int Dig_number=0,Cur_positoin=i+1;62while(isdigit(Exp_arry[Cur_positoin]) || Exp_arry[Cur_positoin]=='.')63 {64 Dig_number++;65 Cur_positoin++;66 }67if(Dig_number >= 16)//最多能够计算15位有效数字68return1;69 }70 }71return0;72 }7374void Evalua()75 {//先调⽤Conver函数将字符串操作单元化,再调⽤Calculate函数计算结果并输出76char Exp_arry[Expmax_length];77int flag=0;//假设刚开始不合法,1表达式合法,0不合法78struct Ope_unit Opeunit_arry[Expmax_length];7980 getchar();//吃掉⼀个换⾏符81 printf("请输⼊四则运算表达式,以=结尾:\n");82 gets(Exp_arry);83 flag=Check(Exp_arry);84if(flag)85 printf("该表达式不合法!\n");86else87 {88int Opeunit_count = Conver(Opeunit_arry,Exp_arry);89double ans = Calculate(Opeunit_arry,Opeunit_count,flag);90if(flag)91 {92 printf("计算结果为:\n");93 printf("%s%lf\n",Exp_arry,ans);94 }95else96 printf("该表达式不合法!\n");97 }98 system("pause");99 }100101int Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[])102 {//将字符串操作单元化103int Explength=strlen(Exp_arry);104int i,Opeunit_count=0;105for(i=0;i<Explength;i++)106 {107if(Isoper(Exp_arry[i]))//是操作符108 {109 Opeunit_arry[Opeunit_count].flag=0;110 Opeunit_arry[Opeunit_count++].oper=Exp_arry[i];111 }112else//是操作数113 {114 Opeunit_arry[Opeunit_count].flag=1;115char temp[Expmax_length];116int k=0;117for(; isdigit(Exp_arry[i]) || Exp_arry[i]=='.' ;i++)118 {119 temp[k++]=Exp_arry[i];120 }121 i--;122 temp[k]='\0';123 Opeunit_arry[Opeunit_count].real=atof(temp);//将字符转化为浮点数124125//负数126if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0127 && Opeunit_arry[Opeunit_count-1].oper=='-')128 {129 Opeunit_arry[Opeunit_count-1].flag = -1;130 Opeunit_arry[Opeunit_count].real *= -1;131 }// -9132if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0133 && Opeunit_arry[Opeunit_count-1].oper=='-' && Opeunit_arry[Opeunit_count-2].flag==0 134 && Opeunit_arry[Opeunit_count-2].oper !=')')135 {136 Opeunit_arry[Opeunit_count-1].flag = -1;137 Opeunit_arry[Opeunit_count].real *= -1;138 }// )-9139140//正数141if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0142 && Opeunit_arry[Opeunit_count-1].oper=='+')143 {144 Opeunit_arry[Opeunit_count-1].flag = -1;145 }// +9146if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0147 && Opeunit_arry[Opeunit_count-1].oper=='+' && Opeunit_arry[Opeunit_count-2].flag==0148 && Opeunit_arry[Opeunit_count-2].oper !=')')149 {150 Opeunit_arry[Opeunit_count-1].flag = -1;151 }// )+9152 Opeunit_count++;153 }154 }155/*for(i=0;i<Opeunit_count;i++)156 {//查看各操作单元是否正确,1是操作数,0是操作符157 if(Opeunit_arry[i].flag == 1)158 printf("该单元是操作数为:%lf\n",Opeunit_arry[i].real);159 else if(Opeunit_arry[i].flag == 0)160 printf("该单元是操作符为:%c\n",Opeunit_arry[i].oper);161 else162 printf("该单元是负号符为:%c\n",Opeunit_arry[i].oper);163 }*/164return Opeunit_count;165 }166167double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag)168 {//根据运算规则,利⽤栈进⾏计算169int i,dS_pointer=0,oS_pointer=0;//dS_pointer为操作数栈顶指⽰器,oS_pointer为操作符栈顶指⽰器170double Dig_stack[Expmax_length];//操作数栈(顺序存储结构)171char Ope_stack[Expmax_length];//操作符栈172173for(i=0;i<Opeunit_count-1;i++)174 {175if( Opeunit_arry[i].flag != -1 )176 {177if(Opeunit_arry[i].flag)//是操作数178 {179 Dig_stack[dS_pointer++]=Opeunit_arry[i].real;//⼊操作数栈180//printf("%lf\n",Digit[dS_pointer-1]);181 }182else//是操作符 + - * / ( )183 {184//操作符栈为空或者左括号⼊栈185if(oS_pointer==0 || Opeunit_arry[i].oper=='(')186 {187 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;188//printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);189 }190else191 {192if(Opeunit_arry[i].oper==')')//是右括号将运算符⼀直出栈,直到遇见左括号193 {194 oS_pointer--;//指向栈顶195 dS_pointer--;//指向栈顶196while(Ope_stack[oS_pointer] != '(' && oS_pointer != 0)197 {198 Dig_stack[dS_pointer-1] = Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 199 Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈200201 dS_pointer--;//前⼀个操作数出栈202//printf("操作数栈顶元素等于%lf\n",Digit[dS_pointer]);203 }204 oS_pointer--;//左括号出栈205206 oS_pointer++;//恢复指向栈顶之上207 dS_pointer++;208 }209else if(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer-1]))//和栈顶元素⽐较210 {211 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;212//printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);213 }214else//运算符出栈,再将该操作符⼊栈215 {216 oS_pointer--;//指向栈顶217 dS_pointer--;//指向栈顶218while(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer])==0 && oS_pointer != -1) 219 {//当前操作符⽐栈顶操作符优先级⾼220 Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 221 Ope_stack[oS_pointer--]);222 dS_pointer--;223//printf("操作数栈顶元素等于%lf\n",Digit[dS_pointer]);224 }225 oS_pointer++;//恢复指向栈顶之上226 dS_pointer++;227 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;228 }229 }230 }231 }232 }233/*for(i=0;i<oS_pointer;i++)234 printf("操作符栈%oS_pointer\Ope_u_count",Operator[i]);235 for(i=0;i<dS_pointer;i++)236 printf("操作数栈%lf\n",Digit[i]);*/237 oS_pointer--;//指向栈顶元素238 dS_pointer--;//指向栈顶元素239while(oS_pointer != -1)240 {241 Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 242 Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈243 dS_pointer--;//前⼀个操作数出栈244//printf("操作数栈顶元素为%lf\Ope_u_count",Digit[dS_pointer]);245 }246//printf("%dS_pointer,%dS_pointer\n",oS_pointer,dS_pointer);247if(oS_pointer==-1 && dS_pointer==0)248 flag=1;//为1表⽰表达式合法249return Dig_stack[0];250 }251252int Ope_Compar(char ope1,char ope2)253 {//操作符运算优先级⽐较254char list[]={"(+-*/"};255int map[5][5]={//先⾏后列,⾏⽐列的运算级优先级低为0,⾼为1256// ( + - * /257/* ( */1,0,0,0,0,258/* + */1,0,0,0,0,259/* - */1,0,0,0,0,260/* * */1,1,1,0,0,261/* / */1,1,1,0,0 };262int i,j;263for(i=0;i<5;i++)264if(ope1==list[i]) break;265for(j=0;j<5;j++)266if(ope2==list[j]) break;267return map[i][j];268 }269270double Four_arithm(double x,double y,char oper)271 {//四则运算272switch(oper)//保证不含其它运算符273 {274case'+': return x+y;275case'-': return x-y;276case'*': return x*y;277case'/': return x/y;//y不能为0278default : return0;279 }280 }281282int Isoper(char ch)283 {//判断合法字符 + - * / ( ) =284if(ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='(' || ch==')' || ch=='=')285return1;286return0;287 }288289void Display()290 {//打印菜单291 system("cls");292 printf("/******************************************************************************/\n");293 printf("\t\t 欢迎使⽤本四则运算表达式求值系统\n");294 printf("\n\t说明:建议请您先阅读使⽤说明,再输⼊相应的数字进⾏操作,谢谢配合!\n"); 295 printf("\n\t\t1 四则运算表达式求值\n");296 printf("\n\t\t2 使⽤说明\n");297 printf("\n\t\t0 退出\n");298 printf("/******************************************************************************/\n");299 }300301void Instru()302 {//打印使⽤说明303 FILE *fp;304char ch;305if( ( fp=fopen("使⽤说明.txt","r") ) == NULL)306 {307 printf("⽂件打开失败!\n");308 exit(0);309 }310for(; (ch = fgetc(fp)) != EOF; )311 putchar(ch);312 fclose(fp);313 printf("\n");314 system("pause");315 }。
数据结构实验报告-表达式求值与任务调度
数据结构与程序设计实验实验报告哈尔滨工程大学实验报告二printf("序号开始时间等待时间结束\n");que[0]=0;rear=1;T[0].start=0;i=0;t=0;j=1;while(i<n){t++;//时间移动i+=check(tdiff);//时间移动后检查是否有完成的任务,并且就算等待时间if(t>=T[j].t&&j<n){//假入在当前任务执行时间内有任务提交insert(j); //把任务插入到队列j++;qsort(que, rear, sizeof(que[0]), comp);//按时间长短排序}if(T[que[0]].start==-1)//给队列最前点赋起始值T[que[0]].start=t;}for(i=0;i<n;i++)//计算出所有等待时间sum+=T[i].wait;printf("平均等待时间为%.3lfs\n\n",sum/n);}四、界面设计1.表达式求值需要输入以’#’结尾的中缀表达式,以提示语句的方式给出。
输出注明是什么结果。
2.任务调度需要输入任务数,任务需要执行时间,(不同时需要任务提交时间),按平均等待时间最短为原则,输出出任务的执行顺序。
五、运行测试与分析1.表达式求值1).输入一个以’#’结尾的中缀表达式:2).输出计算结果,后缀表达式以及前缀表达式:3.任务调度:(1). 同时提交i).输入:ii).输出:(2). 不同时间提交i).输入:ii).输出:六、实验收获与思考1.熟练掌握栈的定义及使用。
2.了解表达式求值的转换算法。
设计前、后缀表达式求值算法。
3.设计操作数为多位实数,操作符为加、减、乘、除、求模的中缀表达式求值算法。
定义算数符号的优先级。
数据结构表达式求值实验报告
数据结构表达式求值实验报告一、实验目的本次实验的主要目的是通过实现表达式求值的程序,深入理解数据结构和算法在解决实际问题中的应用。
具体包括掌握栈这种数据结构的操作和使用,熟悉表达式的转换和计算过程,提高编程能力和问题解决能力。
二、实验环境本次实验使用的编程语言为C++,开发工具为Visual Studio 2019。
三、实验原理表达式求值是程序设计中的一个常见问题,通常采用栈这种数据结构来实现。
表达式可以分为中缀表达式、后缀表达式和前缀表达式。
中缀表达式是我们日常使用的表达式形式,如“2 +3 4”,但直接对中缀表达式求值比较复杂。
而后缀表达式(如“2 3 4 +”)和前缀表达式(如“+2 3 4”)求值相对简单。
因此,在实现表达式求值时,通常先将中缀表达式转换为后缀表达式,然后对后缀表达式进行求值。
转换过程中,使用两个栈,一个用于存储操作数,另一个用于存储运算符。
求值过程中,根据后缀表达式的特点,从左到右依次处理操作数和运算符,进行相应的计算。
四、实验步骤1、定义数据结构定义栈类,用于存储操作数和运算符。
定义一个结构体来表示操作数和运算符。
2、中缀表达式转后缀表达式从左到右扫描中缀表达式。
遇到操作数,直接输出。
遇到运算符,根据其优先级与栈顶运算符的优先级进行比较,决定入栈或出栈操作。
3、后缀表达式求值从左到右扫描后缀表达式。
遇到操作数,入栈。
遇到运算符,从栈中取出两个操作数进行计算,将结果入栈。
4、主函数输入中缀表达式。
调用转换函数和求值函数,输出计算结果。
五、实验代码```cppinclude <iostream>include <stack>include <string>//定义操作符的优先级int priority(char op) {if (op =='+'|| op =='')return 1;if (op ==''|| op =='/')return 2;return 0;}//中缀表达式转后缀表达式std::string infixToPostfix(std::string infix) {std::stack<char> opStack;std::string postfix ="";for (char c : infix) {if (isdigit(c)){postfix += c;} else if (c =='('){} else if (c ==')'){while (!opStackempty()&& opStacktop()!='('){postfix += opStacktop();opStackpop();}opStackpop();//弹出'('} else {while (!opStackempty()&& priority(opStacktop())>=priority(c)){postfix += opStacktop();opStackpop();}opStackpush(c);}}while (!opStackempty()){postfix += opStacktop();}return postfix;}//后缀表达式求值int evaluatePostfix(std::string postfix) {std::stack<int> operandStack;for (char c : postfix) {if (isdigit(c)){operandStackpush(c '0');} else {int operand2 = operandStacktop();operandStackpop();int operand1 = operandStacktop();operandStackpop();switch (c) {case '+':operandStackpush(operand1 + operand2);break;case '':operandStackpush(operand1 operand2);break;case '':operandStackpush(operand1 operand2);break;case '/':operandStackpush(operand1 / operand2);break;}}}return operandStacktop();}int main(){std::string infixExpression;std::cout <<"请输入中缀表达式: ";std::cin >> infixExpression;std::string postfixExpression = infixToPostfix(infixExpression);int result = evaluatePostfix(postfixExpression);std::cout <<"表达式的计算结果为: "<< result << std::endl;return 0;}```六、实验结果输入不同的中缀表达式,如“2 +3 4”“( 2 + 3 )4”等,程序能够正确地将其转换为后缀表达式,并计算出结果。
数据结构课程设计算术表达式求值
计算机科学系《数据结构课程设计》报告课题名称:算术表达式求值目录1.问题描述-----------------------------------------------------------32.基本要求-----------------------------------------------------------33.工具/准备工作----------------------------------------------------34.分析与实现--------------------------------------------------------45. 课程设计体会与感悟------------------------------------------161.问题描述从键盘上输入中缀算术表达式,包括括号,计算出表达式的值。
2.基本要求(1)程序能对所输入的表达式做简单的判断,如表达式有错,能给适当提示。
(2)能处理单目运算符:+,-。
3.工具/准备工作在开始项目之前,应回顾复习相关内容。
需要一台计算机装有visual C++。
4.分析与实现对于中缀表达式,一般运算规则如下:(1)先乘方,再乘除,最后加减;(2)同级运算从左算到右;(3)先括号内再括号外;(4)用到的头文件”utility.h”,”lk_stack.h”,”node.h”,”calculator.h”.根据实践经验,可以对运算符设置统一的优先级,从而方便比较。
表中给出了包括加、上面讨论的的+、—为双目运算符,如为单目运算符,编程实现时,可在前面加上0而转化为双目运算符。
如在+、—的前一个字符(如当前字符不是运算符时,规定用0表示)为‘=’或‘(’,则为单目运算符。
具体实现算法时,可设置两个工作栈,一个为操作栈,一个为操作符栈optr,另外一个为操作数栈opnd,算法基本思路如下:(1)将optr栈和opnd栈清空,在optr栈中加入一个‘=‘。
数据结构(C语言版)课程设计报告表达式求值说明书
数据结构(C语言版)课程设计报告表达式求值说明书XX大学数据结构课程设计说明书题目:表达式求值院系:计算机科学与工程学院专业班级:计算机班学号:学生姓名:指导教师:2021年X月X日XX大学课程设计(论文)任务书计算机科学与工程学院学号学生姓名专业(班级)设计题目表达式求值设计技术参数系统平台:Windows7/WindowsXP开发工具:VC++6.0设计要求(1)能够计算的运算符包括:加、减、乘、除、圆括号。
(2)能够计算的数要求在实数范围内。
(3)能执行多重括号嵌套运算。
(4)对于异常表达式给出错误提示。
工作量课程设计报告要求不少于3000字。
源程序要求不少于300行工作计划2021.11.21-12.01根据课程设计大纲的要求,查找相关资料,完成需求分析;2021.12.02-12.16进行系统的概要设计;2021.12.17-12.31进行系统的详细设计和源代码的书写;2021.01.01-01.17对系统进行调试分析,写出课程设计报告。
参考资料[1]何钦铭主编.C语言程序设计.北京:高等教育出版社,2021.[2]谭浩强编著.C程序设计(第四版).北京:清华大学出版社,2021.[3]严蔚敏,吴伟民编著.数据结构(C语言版)北京:清华大学出版社,2021.[4]严蔚敏,吴伟民编著.数据结构题集北京:清华大学出版社,2021.指导教师签字教研室主任签字2021年X月X日学生姓名:学号:专业班级:课程设计题目:表达式求值指导教师评语:成绩:指导教师:年月日XX大学课程设计(论文)成绩评定表目录1需求分析12概要设计12.1设计思路12.2存储结构设计12.3功能模块设计13详细设计14运行与测试15总结1参考文献2(要求:给出一级目录和二级目录,宋体,四号字,1.5倍行距,页码使用罗马数字,居中)(报告正文部分):(要求:正文部分一律用小四号字,宋体,行距20磅。
一级标题靠左,加粗。
二级大标题靠左,不加粗。
表达式求值(数据结构)
表达式求值(数据结构)表达式求值(数据结构)一、引言表达式求值是计算机科学中一个重要的概念,它是计算机程序中常见的操作之一。
通过对表达式中的运算符和操作数进行计算,可以得到表达式的结果。
本文将介绍表达式求值的相关知识和算法,并提供一个基于数据结构的表达式求值的范本。
二、基本概念1.表达式:由操作数、运算符和括号组成的符号串,用于表示一个计算过程。
2.操作数:表达式中用于参与计算的数值或变量。
3.运算符:表达式中用于进行运算的符号,如加减乘除等。
4.括号:用于控制运算优先级和改变运算次序的符号。
三、表达式求值的算法表达式求值的基本思路是通过遍历表达式字符串并利用栈来进行计算。
1.建立一个操作数栈和一个运算符栈。
2.从左到右遍历表达式字符串,依次处理每个字符。
3.如果当前字符是操作数,则直接入操作数栈。
4.如果当前字符是运算符,则进行如下处理:●如果运算符栈为空或栈顶运算符是左括号,则将当前运算符入运算符栈。
●如果当前运算符的优先级高于栈顶运算符的优先级,则将当前运算符入运算符栈。
●如果当前运算符的优先级低于或等于栈顶运算符的优先级,则从运算符栈顶取出一个运算符进行计算,并将结果入操作数栈,直到栈顶运算符的优先级低于当前运算符,然后将当前运算符入运算符栈。
5.如果当前字符是左括号,则将其入运算符栈。
6.如果当前字符是右括号,则从运算符栈顶取出一个运算符进行计算,并将结果入操作数栈,直到取出的运算符是左括号。
7.遍历完表达式字符串后,将运算符栈中剩余的运算符依次取出进行计算,并将结果入操作数栈。
8.操作数栈中最后剩下的元素即为表达式的求值结果。
四、示例代码```pythonclass ExpressionEvaluation:def __init__(self, expression):self.expression = expressionself.operators = []self.operands = []self.precedence = {'+': 1, '.': 1, '': 2, '/': 2}def evaluate(self):for char in self.expression:if char.isdigit():self.operands.append(int(char))elif char in self.precedence:while self.operators andself.operators[.1] != '(' and self.precedence[char] <= self.precedence[self.operators[.1]]:lculate()self.operators.append(char)elif char == '(':self.operators.append(char)elif char == ')':while self.operators[.1] != '(':lculate()self.operators.pop()while self.operators:lculate()return self.operands[.1]def calculate(self):operator = self.operators.pop()operand2 = self.operands.pop()operand1 = self.operands.pop()if operator == '+':self.operands.append(operand1 + operand2)elif operator == '.':self.operands.append(operand1 ●operand2) elif operator == '':self.operands.append(operand1 operand2) elif operator == '/':self.operands.append(operand1 / operand2) expression = \。
施磊磊的数据结构课程设计及报告2 表达式求值问题
课程设计题目名称表达式求值问题课程名称数据结构课程设计学生姓名施磊磊学号0813022057班级计082指导教师管致锦数据结构课程设计及报告表达式求值一、问题描述实验题目为表达式求值。
要求接受用户输入一个中缀表达式(运算符为加、减、乘、除),然后通过借助于顺序栈实现将其转换为后缀表达式并将其打印,最后求出其值。
设计主函数,使用户可以重复输入中缀表达式,求得表达式的后缀表达式和表达式的值。
二、数据结构算法设计(一)堆栈ADTADT Stack{数据:0个或多个元素的线性序列(a0,a1,...,an-1),其最大允许长度为MaxStackSize。
运算:Create(): 建立一个空栈。
Destroy(): 撤销一个栈。
IsEmpty(): 若空栈,则返回true;否则返回false。
IsFull(): 若栈满,则返回true;否则返回false。
Top(): 在x中返回栈顶元素。
若操作成功,则返回true;否则返回false。
Push(): 在栈顶插入元素x(入栈)。
若操作成功,则返回true;否则返回false。
Pop(): 从栈中删除栈顶元素(出栈)。
若操作成功,则返回true;否则返回false。
Clear(): 清除堆栈中全部元素。
}(二)顺序栈类在此题目中,借助了c++的模板抽象类来定义栈抽象数据类型,程序如下:顺序堆栈类:includetemplateclass Stack{private:T * stack; //指向数组的指针int top; //栈顶指针int maxTop; //最大栈顶指针public:Stack(); //构建一个构造函数;初始化栈void Push(T item); //进栈T Pop(); //出栈,删除栈顶元素T Peek(); //返回栈顶元素bool EmptyStack(); //判断是否为空栈~Stack() {delete []stack;}; //释放并清空栈的存储空间void Clear(){top=-1;} //清除栈中全部元素三、算法原理(一)头文件名在本程序中,运用的头文件有一些是在平时经常用到的,也有一些是少见甚至是很陌生的。
表达式求值(数据结构-栈的应用)
表达式求值(数据结构-栈的应⽤)⼀.问题描述:限制:只含有‘+’,‘-’,‘*’,‘/ ’和圆括号,正整数。
表⽰:字符数组,栈。
中缀表达式:在程序语⾔中,运算符位于两个运算数中间的表达式称为中缀表达式,例如 1+2*3.中缀表达式运算规则:先乘除,后加减,从左到右,先括号内,后括号外,因此中缀表达式不仅要判断运算符的优先级,⽽且还有处理括号。
后缀表达式:运算符在运算数的后⾯,如1+2*3的后缀表达式:1 2 3*,在后缀表达式中已经考虑了运算符的优先级,没有括号,只有运算数和运算符。
后缀表达式的运算:按照运算符的次序进⾏的。
例如123*+,从左到右扫描时,第⼀个运算符为*,先执⾏2*3=6,第⼆个运算符为‘+’,执⾏1+6=7。
⼆ .表达式求值的过程:将算术表达式转换成后缀表达式,然后对后缀表达式求值。
1.将算术表达式转换为后缀表达式。
(1)从左到右⼀次扫描中缀表达式的每⼀个字符,如果是字符串,直接写⼊后缀表达式。
(2)如果遇到的是' ( ',则压⼊操作符栈,遇到‘(’时,将栈中的元素放到后缀表达式中,直达栈顶元素为'('时,将栈顶元素'('删除,不需要⼊栈。
(3)如果遇到的是操作符,则将操作符和操作符栈顶元素⽐较。
:如果a[i]的运算符的优先级⼩于等于栈顶元素的优先级,退栈运算符并放到后缀表达式中,直到a[i]的运算符优先级⼤于栈顶运算符的优先级:否则⼊栈。
(4)重复上述步骤,知道中缀表达式的结束符标记“#”,转换结束。
我的代码:#include<bits/stdc++.h>using namespace std;stack<char>f;//操作符栈stack<double>s;//操作数栈bool flag;int prior(char ch)//运算符的优先级{switch(ch){case'+':case'-':return 1;case'*':case'%':case'/':return 2;default:return 0;//括号}}string trans(string a){while(!f.empty()) f.pop();f.push('#');string ret="";//保存中缀表达式int len=a.size(),i=0;while(i<len){if(a[i]==' '||a[i]=='=')//??{i++;continue;}else if(a[i]=='(')f.push(a[i++]);else if(a[i]==')'){while(f.top()!='('){ret+=f.top();ret+=' ';f.pop();}f.pop();//(出栈i++;}else if(a[i]=='+'||a[i]=='-'||a[i]=='*'||a[i]=='/'||a[i]=='%'){while(prior(f.top())>=prior(a[i]))//如果a[]的运算符的优先级⼩于等于栈顶元素的优先级,退栈运算符并放到后缀表达式中,直到a[i]的运算符优先级⼤于栈顶运算符的优先级ret+=f.top();ret+=' ';f.pop();}f.push(a[i++]);}else{while((a[i]>='0'&&a[i]<='9')||a[i]=='.'){ret+=a[i++];}ret+=' ';}}while(f.top()!='#'){ret+=f.top();ret+=' ';f.pop();}ret+='=';return ret;}double cal(double a,double b,double ch)//计算{if(ch=='+') return a+b;if(ch=='-') return a-b;if(ch=='*') return a*b;if(ch=='%') return ((int)a%(int)b);if(ch=='/'){if(b!=0)return a/b;flag=true;return 0;}}double solve(string a)//后缀表达式计算{string t=trans(a);while(!s.empty()) s.pop();flag=false;int len=t.length(),i=0;while(i<len){if(t[i]==' '||t[i]=='='){i++;continue;}else if(t[i]=='+'||t[i]=='-'||t[i]=='*'||t[i]=='/'||t[i]=='%') {double num1,num2;num1=s.top();s.pop();num2=s.top();s.pop();s.push(cal(num1,num2,t[i]));i++;}else{double x=0;while(t[i]>='0'&&t[i]<='9'){x=x*10+t[i]-'0';i++;}if(t[i]=='.'){double k=10.0,y=0;i++;while(t[i]>='0'&&t[i]<='9'){y+=((t[i]-'0')/k);i++;k*=10;;}x+=y;}s.push(x);}}return s.top();}int main(){int num;scanf("%d",&num);while(num--){cin>>a;// cout<<e.trans(a)<<endl;//将中缀表达式装换为后缀表达式 cout<<solve(a)<<endl;}return 0;}。
数据结构表达式求值
数据结构表达式求值正文:1. 引言本文档旨在介绍数据结构中表达式求值的相关知识和算法。
通过对不同类型的表达式进行解析、转换和计算,可以实现数学运算、逻辑判断等功能。
2. 表达式基础概念2.1 表达式定义:一个由操作符(如加减乘除)、操作数(变量或常量)以及括号组成的序列。
2.2 中缀表示法:将操作符置于两个相邻的操作数之间,例如a +b c。
2.3 后缀表示法:将所有操作符都放到其相关联的两个对象后面,例如 abc+。
3. 中缀转后缀在计算机内部处理表达时通常使用后缀形势更为方便,在此我们需要先把中边形势得出来再做进一步分析与运行4.栈应用-前驱关系图这里是讲述了当遇见某些特殊字符要怎么去处理5.从左至右扫描并分类输入串:这里主要说明了如果用户给定字符串有误该怎样提示错误信息6.数字直接输出, 操作者入堆栈:当检测到当前读取元素是数字就会直接打印7 . 遇到操作符时,比较其与栈顶运算符的优先级:这里主要是讲述了当遇见某些特殊字符要怎么去处理8 . 操作者入堆栈当检测到当前读取元素是数字就会直接打印9. 遇括号则进行如下判断:如果为左括号,则将此运算符压入堆叠。
(2)如果为右括号。
则依次弹出S中的所有运算符,并加至输出串尾部, 直至删除一个相应的左括号(不包含该左扩展)。
10.重复步骤3-6 ,直至表达式结束附件:无法律名词及注释:1. 表达式求值:指对给定数学或逻辑表达式进行计算并得出结果的过程。
2. 中缀表示法:一种常用于书写和理解数学表达式的形式,其中操作符位于两个相关联的对象之间。
3. 后缀表示法(也称逆波兰表示法):一种以后置方式排列操作数和操作符来构造代数、布尔函数等合成函数公式或语言文法规范的记录方法和数据结构.。
数据结构课程设计-表达式求值问题
实验表达式求值问题1. 问题描述表达式是数据运算的基本形式。
人们的书写习惯是中缀式,如:11+22* (7-4 )/3. 中缀式的计算按运算符的优先级及括号优先的原则,相同级别从左到右进行计算。
表达式还有后缀表达式(如:11 22 7 4 - * 3 / + )和前缀表达式(+ 11 / * 22 - 7 4 3 )。
后缀表达式和前缀表达式中没有括号,给计算带来方便。
如后缀表达式计算时按运算符出现的先后进行计算。
本设计的主要任务是进行表达式形式的转换及不同形式的表达式计算。
2. 数据结构设计1)顺序栈类定义:首先应在类中定义成员函数,以此来完成顺序栈的相关操作,如下:class SqStackprivate:T *base; // 栈底指针int top; // 栈顶int stacksize; // 栈容量public:SqStack(int m); // 构建函数~SqStack(){delete [] base;top=0;stacksize=0;} // 析构函数void Push(T x); // 入栈T Pop(); // 出栈T GetTop(); // 获取栈顶元素int StackEmpty(); // 测栈空void ClearStack(); // 清空栈void StackTop(); // 返回栈顶指针void StackTranverse(); // 显示栈中元素};2)顺序栈类实现:对顺序栈进行初始化,初始化的首要操作就是创建一个空顺序栈。
Step1 :申请一组连续的内存空间为顺序栈使用:base=new T[m];i f(base==NULL)cout<<" 栈创建失败,退出!"<<endl; exit(1);}{Step2 :给栈顶、栈容量赋相应的值:stacksize=m;t op=-1;(2)顺序栈入栈:入栈需要在栈顶插入一个新元素并相应的调整栈顶。
数据结构课程设计 表达式的值
目录1 题目的内容及要求 (2)2 需求分析 (2)3 概要设计 (2)4 详细设计 (4)5 源代码 (6)6 运行结果及分析 (13)7 收获及体会 (14)1 题目的内容及要求从文件读取表达式,判断表达式是否合理,将表达式转换成后缀形式,按后缀表达式求值;题目涉及加减乘除,带括弧的混合运算;随时可以退出。
2 需求分析利用栈设计一个程序,该程序能够用于表达式求值,程序将读入的中缀表达式转换为后缀表达式,然后读取后缀表达式,输出结果。
本程序具有检测表达式语法是否正确的功能,如果表达式出现错误的时候,程序会提示操作人员执行的表达式不合理,语法是不能执行的。
语法正常的情况下,程序可以实现了加、减、乘、除以及带括号的基本运算。
程序在执行表达式的时候,先检查表达式是否合理,不合理则输出表达式不符合要求,合理则将中缀表达式转化为后缀表达式,然后则对表达式求值,输出结果。
3 概要设计本程序选用的是线性表数据结构。
它按照后进先出的原则存储数据,先进的数据被压入栈底,最后的数据在栈顶,需要度数据的时候才栈顶开式探出数据。
程序采用的是顺序存储结构,可以将逻辑上相邻的数据元素在物力上相邻的存储单元里,节电之间的关系由存储单元相邻的关系来决定。
选择线性表结构是因为程序是用栈来设计的,可以将优先运算的送至栈顶,低级别的运算则最后根据先后进栈的顺序来执行。
选择顺序存储结构是因为顺序存储结构存取数据数度快,占用的存储空间小。
系统的功能模块划分:Translate()的功能是将中缀表达式转换为后缀表达式DispPostfix()的功能是输出后缀表达式ProcessExpress()的功能是将原表达式进行预处理,检查符号是否匹配,转化为中缀式。
endright的功能是先对表示式的运算符进行处理,考虑其计算的优先级。
FindSymbol()的功能是对表达式的括号进行优先处理。
FindWord()的功能是检查表达式是否有语法错误。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验表达式求值问题1.问题描述表达式是数据运算的基本形式。
人们的书写习惯是中缀式,如:11+22*(7-4)/3.中缀式的计算按运算符的优先级及括号优先的原则,相同级别从左到右进行计算。
表达式还有后缀表达式(如:11 22 7 4 - * 3 / +)和前缀表达式(+ 11 / * 22 - 7 4 3)。
后缀表达式和前缀表达式中没有括号,给计算带来方便。
如后缀表达式计算时按运算符出现的先后进行计算。
本设计的主要任务是进行表达式形式的转换及不同形式的表达式计算。
2.数据结构设计(1)顺序栈类定义:首先应在类中定义成员函数,以此来完成顺序栈的相关操作,如下: class SqStack{private:T *base; //栈底指针int top; //栈顶int stacksize; //栈容量public:SqStack(int m); //构建函数~SqStack(){delete [] base;top=0;stacksize=0;} //析构函数void Push(T x); //入栈T Pop(); //出栈T GetTop(); //获取栈顶元素int StackEmpty(); //测栈空void ClearStack(); //清空栈void StackTop(); //返回栈顶指针void StackTranverse(); //显示栈中元素};(2)顺序栈类实现:对顺序栈进行初始化,初始化的首要操作就是创建一个空顺序栈。
Step1:申请一组连续的存空间为顺序栈使用:base=new T[m];i f(base==NULL){cout<<"栈创建失败,退出!"<<endl;exit(1);}Step2:给栈顶、栈容量赋相应的值:stacksize=m;t op=-1;(2)顺序栈入栈:入栈需要在栈顶插入一个新元素并相应的调整栈顶。
Step1:首先判断是否栈满,如果栈满,抛出“上溢”信息,无法入栈,否则转入Step2;if(top==stacksize-1) throw "栈满,无法入栈";Step2:栈顶指针增加1;top++;Step3:新元素插入栈顶位置;base[top]=x;(3)顺序栈出栈:出栈需要取出栈顶元素,并相应的调整栈顶指针。
Step1:首先判断是否栈空,如果栈空,抛出“下溢”信息,无法出栈,否则转入Step2;i f(top==-1) throw "栈空,不能出栈";Step2:取出栈顶元素,栈顶指针减1;T x;x=base[top--];Step3:返回栈顶元素;return x;(4)顺序栈取栈顶元素:取栈顶元素是取出栈顶元素的值,但不改变栈。
Step1:首先判断是否栈空,如果栈空,抛出“下溢”信息,无法出栈,否则转入Step2;if(top==-1) throw "栈空,栈顶无元素";Step2:取出栈顶元素,返回栈顶元素;return base[top];(5)判断栈空:判断是否栈空,返回Step1:如果栈空,返回1,否则转Step2;if(top==-1)return 1;Step2:否则返回0;return 0;(6)清空栈:将栈清空。
top=-1(7)返回栈顶指针:cout<<"栈顶top= "<<top;(8)输出栈元素:将栈顶指向i,从栈顶输出到栈底。
Step1:将栈顶指针赋予i;int i=top;Step2:如果栈不为空,则输出;while(i>=0)cout<<base[i--]<<'\t';cout<<endl;3.算法设计本实验要求读入中缀表达式,求中缀表达式,将中缀表达式转换成前,后缀表达式,利用前,中,后缀表达式求值,并且能够输出等等操作,这就需要构建相关算法。
(1)首先要将表达式中操作符优先级进行排序,优先级从高到低依次为(,),*,/,+,-,算法如下,利用选择语句比较:char Precede(char t1,char t2){//运算符的优先级比较char f;switch(t2){case '+':case '-':if(t1=='('||t1=='=')f='<';elsef='>';break;case '*':case '/':if(t1=='*'||t1=='/'||t1==')')f='>';elsef='<';break;case '(':if(t1==')'){cout<<"ERROR1"<<endl;exit(0);}elsef='<';break;case ')':switch(t1){case '(':f='=';break;case '=':cout<<"ERROR2"<<endl; exit(0);default: f='>';}break;case '=':switch(t1){case '=':f='=';break;case '(':cout<<"ERROR2"<<endl;exit(0);default: f='>';}}return f;}(2)其次,就是判断输入元素是否为运算符,若为运算符,就输出1,否则输出0; int In(char c){ // 判断c是否为运算符switch(c){case'+':case'-':case'*':case'/':case'(':case')':case'=':return 1;default:return 0;}}(3)构造表达式的运算算法,利用选择语句将运算分类:float Operate(float a,char theta,float b){//实施一次运算float c;switch(theta){case'+':c=a+b;break;case'-':c=a-b;break;case'*':c=a*b;break;case'/':c=a/b;}return c;}(4)要求一:中缀表达式求值Step1:首先需要将运算符和运算数分开存放,这就需要分别创建栈:SqStack<char> OP(20);SqStack<float> OD(20);Step2:创建相关字符来存放由键盘输入的字符,并以“=”键结束char theta;float a,b,d;char c,x; // 存放由键盘接收的字符char z[6]; // 存放符点数字符串int i;OP.Push('=');Step3:当输入为数字元素是,直接存入表达式栈就可以,而当输入是符号元素时,就需要判断优先级并进行存栈出栈操作,如果是非法字符,输出错误,并且不存入;c=*exp++;x=OP.GetTop();while(c!='='||x!='='){if(In(c)) // 是7种运算符之一switch(Precede(x,c)){case'<':OP.Push(c); // 栈顶元素优先权低c=*exp++;break;case'=':x=OP.Pop(); // 脱括号并接收下一字符c=*exp++;break;case'>':theta=OP.Pop(); // 退栈并将运算结果入栈b=OD.Pop();a=OD.Pop();OD.Push(Operate(a,theta,b));}else if(c>='0'&&c<='9'||c=='.') // c是操作数{i=0;do{z[i]=c;i++;c=*exp++;}while(c>='0'&&c<='9'||c=='.');z[i]='\0';d=atof(z); // 将字符串数组转为符点型存于d OD.Push(d);}else // c是非法字符{cout<<"ERROR3"<<endl;;exit(0);}x=OP.GetTop();}d=OD.GetTop();return d;}(4)中缀表达式转换成后缀表达式:Step1:创建一个操作符栈;char c,x;int i=0;SqStack<char> OP(20);Step2:从左到右扫描读取表达式,执行下列运算,直至表达式结束符。
SqStack<char> OP(20);OP.Push('='); // =是表达式结束标志cout<<"exp:"<<exp<<endl;c=*exp++;2.1:如果是操作数,输出;if((c>='0'&&c<='9')||c=='.'){postexp[i++]=c;c=*exp++;}2.2:如果是操作符A2,把操作符栈栈顶的操作符A2与它比较:2.2.1:A1<A2,A2如操作符栈。
2.2.2:A1=A2,从操作符栈退出一个操作符,不输出。
2.2.3:A1>A2,从操作符栈输出所有比A2优先级高的运算符,直至栈顶算符优先级小于A2,A2如操作符栈。
if(In(c)) // 是7种运算符之一{postexp[i++]=' ';x=OP.GetTop();switch(Precede(x,c)){case'<':OP.Push(c); // 栈顶元素优先权低c=*exp++;break;case'=':x=OP.Pop(); // 脱括号并接收下一字符c=*exp++;break;case'>':postexp[i++]=OP.Pop(); // 运算符出栈输出break;}}postexp[i]='\0';(4)中缀表达式转换成前缀表达式:Step1:创建一个操作符栈;char c,x;int i=0;SqStack<char> OP(20);Step2:从右到左扫描读取表达式,执行下列运算,直至表达式结束符;while(*exp != '\0')*exp++;O P.Push('='); // =是表达式结束标志c=*exp--;2.1:如果是操作数,输出;if((c>='0'&&c<='9')||c=='.'){preexp[i++]=c;c=*exp--;}2.2:如果是操作符A2,把操作符栈栈顶的操作符A2与它比较:2.2.1:A1<A2,A2如操作符栈。