表达式求值课程设计报告
数据结构表达式求值实验报告

竭诚为您提供优质文档/双击可除数据结构表达式求值实验报告篇一:数据结构实验二——算术表达式求值实验报告《数据结构与数据库》实验报告实验题目算术表达式求值学院:化学与材料科学学院专业班级: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、设计要求:给定一个算术表达式,通过程序求出最后的结果 1>、从键盘输入要求解的算术表达式; 2>、采用栈结构进行算术表达式的求解过程; 3>、能够判断算术表达式正确与否;4>、对于错误表达式给出提示;5>、对于正确的表达式给出最后的结果; 2、设计构想:为了实现算符优先算法使用两个工作栈,一个称作OPTR,以寄存运算符;另一个称作OPND,用以寄存操作数或运算结果。
在操作数和操作符入栈前,通过一个函数来判别,输入的是操作数还是操作符,操作数入OPND,操作符入OPTR。
在输入表达式的最后输入‘#’,设定‘#’的优先级最低,代表表达式输入结束。
在表达式输入过程中,遇操作数则直接入栈,遇到运算符则与栈顶运算符比较优先级,若当前运算符优先级高,则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符与新栈顶运算符。
如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。
二、概要设计1、本程序包含的模块:栈模块——实现栈抽象数据类型运算模块——实现数据表达式的运算主程序模块算术运算式的求解栈模块主函数模块main 运算模块定义栈结构初始化栈出栈入栈取栈顶元素判断输入字符类型判断符号优先级基础运算函数运算函数三、详细设计栈模块1、定义栈结构 struct Sqstack{elemtype *top;//栈顶元素 elemtype *base; //栈底元素 int stacksize;//栈的大小 };2、栈的基本操作①初始化栈status initstack(struct Sqstack &s) {=(elemtype *)malloc(stack_size*sizeof(elemtype)); if(!) return OVERFLOW; =;=stack_size; return OK; } ②入栈status push(struct Sqstack &s,elemtype e) {if(>=) {=(elemtype*)realloc(,(+stack_increasement)*sizeof(elemtype));if(! ) return OVERFLOW; =+; +=stack_increasement; } * ++=e; return OK; } ③出栈elemtype pop(struct Sqstack &s) {elemtype e; if(= =) return ERROR; e=*--;return e; }④取栈顶元素elemtype gettop(struct Sqstack &s) {elemtype e; if(==) return ERROR; e=* ; return e; } 运算模块1、判断输入字符c是否为操作符:若是,则返回1;否则,返回0 int In(int c) {char p[10]=\ int i=0;while(p[i]!='\\0') {if(p[i]==c) return 1;i++; } return 0; }2、判断运算符的优先级char precede(char top,char c)//该函数为判断当前运算符与前一个运算符的优先级,前一个运算符高于或等于当前运算符的优先级则返回‘>’,前一个运算符小于当前运算符的优先级则返‘'; break; case '+': case '-':if(top=='#'||top=='(')result=''; break; case '*': case '/':if(top=='*'||top=='/'||top=='^') result='>'; elseresult=''; elseresult=''; break;case '(': result='': theta=pop(optr); b=pop(opnd); a=pop(opnd); push(opnd,operate(a,theta,b)); break;// 若当前操作符的优先级低于操作符栈的栈顶元素,则将操作符栈栈顶元素出栈,并将操作数栈的栈顶两个元素出栈,计算两个元素间以操作符栈栈顶元素为运算符的数学运算}//switch }//if}//whilereturn pop(opnd); }主程序模块1、main函数void main(int argc,char *argv) {struct Sqstack opnd; //操作数栈 struct Sqstack optr;//操作符栈initstack(opdn); initstack(optr); elemtype result;printf(\ printf(\算术运算式的求解\printf(\ printf(\请输入算术运算表达式(以'#'结尾):\\n\ printf(\result=evaluate(opnd,optr);printf(\printf(\运算的结果是 :\\n \\n%d\\n\printf(\}四、调试分析 1、测试结果1> 测试数据:3+7*2-1# 测试结果:2> 测试数据:(3+7)*2-1# 测试结果:3> 测试数据: 1/0# 测试结果:2、程序时间复杂度为O;3、设计中出现的问题:在开始的设计中没有注意除数不能为0 ,后来加入if(b==0) {printf(\分母为0,the result is error\\n\ result=0; } elseresult=a/b;break;来判断除数是否为0 4、算法改进:1>输入的操作数和操作码于是字符串类型的,在原设计中实现的操作都是对个位数实现的,实用性不大,故在后来的设计中,通过一个标志flag实现了标志操作数的连续输入的判别,继而实现了多位数的表达式运算2>开始只实现了加、减、乘、除及带小括号的数学运算,考虑到实用性,在后来的设计中引入pow函数,实现了乘方的运算,调整结果如下:3>最初设计的运行界面过于单调,不够友好,改进时加入一些*调整调整结果如下:五、课程设计总结本学期是我第一次接触课程设计,发现了很多学习上的问题,也有很多收获。
表达式求值课程设计报告

目录1 需求分析 (1)1.1问题描述 (1)1.2基本要求 (1)2 概要设计 (1)2.1 数据结构 (1)2.2 各模块间的调用关系及算法设计 (2)2.2.1 栈的抽象数据类型的定义 (3)2.2.2栈的基本功能 (4)3 详细设计 (6)3.1数据存储结构设计 (6)3.2 主函数和其它函数的设计与实现 (6)3.3函数功能分析 (8)3.4 函数间的调用关系 (9)4 调试与分析 (9)4.1 程序调试 (9)4.2 数据分析 (12)5 用户手册 (13)5.1 运行环境 (13)5.2 执行文件 (13)6 参考文献 (13)7 心得体会 (13)8小组成员任务分配及工作进度安排 (14)1 需求分析1.1问题描述在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。
因而在程序设计时,借助栈实现。
算法输入:一个算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)操作符为+、-*、/,用#表示结束。
算法输出:表达式运算结果。
算法要点:设置运算符栈和运算数栈辅助分析算符优先关系。
在读入表达式的字符序列的同时,完成运算符和运算数的识别处理,以及相应运算。
本算法的时间复杂度与输入的表达式的长度有密切的关系,在此不作深入分析。
1.2基本要求设计友好的用户界面,利用所学工具开发一个简单的表达式求值应用程序,该程序能够对表达式进行加、减、乘、除运算,表达式中的操作数要求在实数范围内;对于异常表达式应能给出错误提示。
针对前面的要求分别设计合理的测试数据,比如3.154*(12+18)-23的结果应该是71.62等。
2概要设计2.1 数据结构表达式求值是程序设计语言编译中的一个最基本的问题。
它的实现是栈应用的一个典型例子。
本程序使用通常使用的算法为“算符优先法”。
要把一个表达式翻译成正确求值的一个机器指令序列,或者直接对求值首先要能够正确解释表达式。
数据结构课程设计报告-表达式求值

《数据结构》课程设计利用栈求表达式的值班级: 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)。
C语言表达式计算课设报告

目录一、需要分析 (2)1) 课题要求 (2)2) 课题分析 (2)3) 实现功能步骤 (2)4) 承担模块工作详解 (2)5) 运行环境 (2)二、概要设计 (3)1) 系统流程图 (3)2) 提示输入模块 (4)3) 表达式正误判断模块 (4)4) 中缀表达式转为后缀表达式模块 (4)5) 后缀表达式计算模块 (4)三、详细设计 (4)1) main函数模块 (4)2) 提示输入模块 (5)3) 表达式正误判断 (6)4) 中缀表达式转为后缀表达式 (7)5) 后缀表达式的计算 (9)四、调试分析 (14)1) 调试过程中遇到的问题和解决方法 (14)2) 经验和体会 (14)五、用户使用说明 (14)六、测试结果 (15)七、参考文献 (17)八、附录 (18)图表目录图表 1 .1 输入提示 (15)图表 2 .1 输入选择错误 (15)图表 3 .1 正常表达式计算 (16)图表 4 .1表达式错误提示 (17)第1页一、需要分析1) 课题要求表达式计算(难度:B)要求:输入一个表达式,输出其结果。
表达式由数字、运算符(+ - * / ( ) )常用数学函数组成。
例如,输入3*(sqrt(64)+(4/3)),输出28。
此外,如果输入的是错误的表达式,则提示错误。
例如:2+*3则输出:表达式输入错误。
2) 课题分析根据课题要求应该做到以下几点:①提示输入,输出提示内容。
包括数的类型(浮点型),运算符种类(+、-、*、/),函数的种类(sqrt(x)、log(x)、fabs(x)、sin(x)、cos(x)、tan(x))。
②主函数中设置计算循环,实现可以运算多个表达式,并设置退出表达式计算按钮。
③实现表达式的正误判断,错误返回0并输出表达式错误,正确返回1。
④实现将中缀表达式转为后缀表达式的处理,返回后缀表达式。
⑤实现后缀表达式的运算,返回最后数值。
3) 实现功能步骤由提示输入,输入“1”按回车进行表达式计算,输入要计算的表达式按回车就可以得出结果,由提示输入,输入“2”按回车退出表达式的计算程序。
数据结构课程设计-表达式求值【完整版】

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、算法:建立两个不同类型得空栈,先把一个‘#’压入运算符栈。
数据结构表达式求值完整篇(含实验报告)

的是p*low),继续输入ch
总结:
我觉得写的好的地方在于定义了flag,low分别作为小数入栈和负号与减号区别的条
件。第一次写这么长的代码,还有就是将输入的字符再转到小数这段代码可以留着很有 用。开始考虑的大整数想麻烦了,直接用double难度降低了很多
4
【列岀你的测试结果,包括输入和岀。测试数据应该完整和严格,最好多于需求分析中所列。】
if(!s.base)
printf("\n运算符栈存储分配失败!\n");
s.top=s.base;
s.stacksize=MAXSIZE;
}
//
void OPND」n itStack(Sqstack_OPND &s)
{
s.base=new SElemType_OPND[MAXSIZE];
if(!s.base)
操作数和运算符分别入不同的栈charint进操作数栈先考虑了小于10的整数直接进栈重点是运算符的优先级这块函数的编写前面的都听简单的就是小数编写这块想了很久定义了low做判定符号的标志
数据结构表达式求值完整篇(含 实验报告)
1
(1)深入理解栈的特点及其描述方法
(2)能够在两种存储结构上实现栈抽象数据类型实现
&s,SElemType_OPND&e); //出栈
/*
#i nclude "common .h"
#include "Sqstack.h"
#in clude "other.h"
//
void OPTR_I ni tStack(Sqstack_OPTR &s)
{
表达式求值c++ 数据结构课设报告

数据结构课程设计院别计算机与通信工程学院专业计算机科学与技术班级学号姓名指导教师成绩2013 年7 月18 日目录一、设计课题 (3)二、需求分析 (3)三、算法设计 (3)四、调试分析 (9)五、用户手册 (10)六、测试结果 (10)七、附录(源代码) (13)八、参考文献 (21)一、设计课题: 表达式求值 二、需求分析:当用户输入一个合法的算术表达式后,能够返回正确的结果。
能够计算的运算符包括:加、减、乘、除、括号;能够计算的操作数要求在实数范围内;对于异常表达式能给出错误提示。
三、算法设计:概要说明:为实现上述程序功能,1. 首先置操作数栈为空栈,表达式起始符#为运算符栈的栈底元素;2. 依次扫描表达式中每个字符,若是操作数则进OPND 栈;若是运算符,则和OPTR 栈的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕。
3. 先做一个适合个位的+-*/运算, 其次就要考虑到对n 位和小数点的运算。
模块间调用关系:调用主程序模块————>输出模块详细说明(ADT 描述) :ADT SqStack{数据对象:D={i a |i a ∈ElemSet,i=1,2,…,n, n ≧0} 数据对象:R1={<1,-i i a a >|1-i a ,D a i ∈,i=2,…,n}约定n a 端为栈顶,i a 端为栈底。
基本操作:InitStack(&S)操作结果:构造一个空栈S 。
GetTop(S)初始条件:栈S 已存在。
操作结果:用P 返回S 的栈顶元素。
Push(&S ,e)初始条件:栈S 已存在。
操作结果:插入元素ch 为新的栈顶元素。
Pop(&S ,e)初始条件:栈S 已存在。
操作结果:删除S 的栈顶元素。
In(c)操作结果:判断字符是否是运算符,运算符即返回1。
Precede(c1, c2)初始条件:c1,c2为运算符。
操作结果:判断运算符优先权,返回优先权高的。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
表达式求值课程设计报告表达式求值《数据结构》课程设计报告题目: 栈的应用:表达式求值(系): 信息科学与工程学院院专业班级: 软件工程1102班学生姓名:学号: 指导教师:20 13 年 6 月 8 日至20 13 年 6 月 21 日表达式求值目录目录 (2)1 概述 (1)1.1 课程设计目的 (1)1.2 课程设计内容 (1)2 系统需求分析 ......................................................12.1 系统目标 (1)2.2 主体功能 (1)2.3 开发环境 (1)3 系统概要设计 ....................................................23.1 系统的功能模块划分 (2)3.2 系统流程图 (2)4系统详细设计 .....................................................35 测试 ............................................................65.1 测试方案 (6)5.2 测试结果 (6)6 小结 ............................................................8参考文献 ..........................................................9附录1 源程序清单 (10)2数据结构课程设计报告(2012)表达式求值1 概述1.1 课程设计目的1(要求学生达到熟练掌握C语言的基本知识和技能。
2(了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力。
3(提高程序设计和调试能力。
学生通过上机实习,验证自己设计的算法的正确性。
学会有效利用基本调试方法,迅速找出程序代码中的错误并且修改。
4(培养算法分析能力。
分析所设计算法的时间复杂度和空间复杂度,进一步提高程序设计水平。
5(初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能。
1.2 课程设计内容设计一个表达式求值的程序。
该程序必须可以接受包含(,),+,-,*,/,%,b和^(求幂运算符,a^b=a)的中缀表达式,并求出结果。
如果表达式正确,则输出表达式的结果;如果表达式非法,则输出错误信息。
2 系统需求分析2.1 系统目标利用栈设计一个程序,该程序能够用于表达式求值,程序将读入的中缀表达式转换为后缀表达式,然后读取后缀表达式,输出结果。
输入要求:程序从“input.txt”文件中读取信息,在这个文件中如果有多个中缀表达式,则每个表达式独占一行,程序的读取操作在文件的结尾处停止。
输出要求:对于每一个表达式,将其结果放在“output.txt”文件的每一行中。
这些结果可能是值(精确到小数点后两位),也可能是错误信息“ERROR IN INFIXNOTATION”。
2.2 主体功能能够处理以字符序列的形式输入的不含变量的实数表达式,正确处理负数与小数,判断表达式是否语法正确(包含分母不能为零的情况),正确实现对算术四则混合运算表达式的求值,能够将计算中遇到的问题和结果以文件的形式予以存储。
2.3 开发环境Microsoft Visual C++ 6.01表达式求值3 系统概要设计3.1 系统的功能模块划分1.判断操作数的函数isnum()判断当前所指字符是否属于数字,是就返回‘1’,不是就返回‘0’。
2.求运算符优先级函数priority()为了方便判断运算符优先级,先利用switch函数将不同的运算符返回不同的整型数字,在根据数字的大小判断优先级。
‘+’,‘-’优先级相同,返回数字相同,‘*’,‘/’也是。
3.表达式求值函数infix_value()此函数是直接按照设计思路完成问题要求的函数,其中要调用到判断操作符的函数isnum()和求运算符优先级的函数priority()。
循环结束弹出栈2的数值,并返回。
4.主函数main()定义一个数组存储表达式整个字符串,将返回的数值直接赋值到浮点型的result,输出result。
5.两个栈的函数设计:栈的初始化函数charInit_SeqStack()Init_SeqStack()栈判空 Empty_SeqStack()char Empty_SeqStack()入栈函数 Push_SeqStack()charPush_SeqStack()出栈函数 Pop_SeqStack()charPop_SeqStack()取栈顶函数 GetTop_SeqStack()charGetTop_SeqStack()销毁栈 Destory_SeqStack()charDestory_SeqStack() 3.2 系统流程图2数据结构课程设计报告(2012)开始优先级比较算法Operate 算法建立栈存放操作字符存放数据计算表达式式否合法输出错误提输出表达式值示结束图1 系统流程图4系统详细设计1. 基本分析:在计算机中,算术表达式的计算往往是通过使用栈来实现的。
所以,本表达式求值程序的最主要的数据结构就是栈。
可以使用栈来存储输入表达式的操作符和操作数。
输入的表达式是由操作数和运算符以及改变运算次序的圆括号连接而成的式子。
表达式求值是高级语言编译中的一个基本问题,是栈的典型应用实例。
任何一个表达式都是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。
操作数既可以是常数,也可以是被说明为变量或常量的标识符;运算符可以分为算术运算符、关系运算符和逻辑运算符三类;基本界限符有左右括号和表达式结束符等。
2. 中缀表达式求值:中缀表达式:每个二目运算符在两个运算量的中间,假设操作数是整型常数,运算符只含加、减、乘、除等四种运算符,界限符有左右括号和表达式起始、结束3表达式求值符“,”,如:,(7+15)*(23-28/4),。
要对一个简单的算术表达式求值,首先要了解算术四则运算的规则,即:(1) 从左到右;(2) 先乘除,后加减;(3) 先括号内,后括号外。
运算符和界限符可统称为算符,它们构成的集合命名为OPS。
根据上述三条运算规则,在运算过程中,任意两个前后相继出现的算符θ1和θ2之间的优先关系必为下面三种关系之一:θ1<θ2,θ1的优先权低于θ2。
θ1=θ2,θ1的优先权等于θ2。
θ1>θ2,θ1的优先权高于θ2。
实现算符优先算法时需要使用两个工作栈:一个称作operator,用以存放运算符;另一个称作operand,用以存放操作数或运算的中间结果。
算法的基本过程如下:首先初始化操作数栈operand和运算符栈operator,并将表达式起始符“,”压入运算符栈;依次读入表达式中的每个字符,若是操作数则直接进入操作数栈operand,若是运算符,则与运算符栈operator的栈顶运算符进行优先权比较,并做如下处理:(1) 若栈顶运算符的优先级低于刚读入的运算符,则让刚读入的运算符进operator栈;(2) 若栈顶运算符的优先级高于刚读入的运算符,则将栈顶运算符退栈,送入θ,同时将操作数栈operand退栈两次,得到两个操作数a、b,对a、b进行θ运算后,将运算结果作为中间结果推入operand栈;(3) 若栈顶运算符的优先级与刚读入的运算符的优先级相同,说明左右括号相遇,只需将栈顶运算符(左括号)退栈即可。
operator栈的栈顶元素和当前读入的字符均为“#”时,说明表达式起始符“#”与表达式结束符“#”相遇,整个表达式求解结束。
int ExpEvaluation(){ /*读入一个简单算术表达式并计算其值。
*/InitStack(&operand); InitStack(&operator);PushStack(&operator, ’,’);printf(″\n\n Please input an expression (Ending with ,) :″);ch=getchar(); /*读入表达式中的一个字符*/while(ch!=‘,’||GetTop(operator)!=‘,’){ if(!In(ch, OPS)) /*判断ch是否运算符*/{ a=GetNumber(&ch); /* 用ch逐个读入操作数的各位数码,并转化为十进制数a */PushStack(&operand,a);}elseswitch(Compare(GetTop(operator),ch)){ case ′<′: PushStack(&operator, ch); ch=getchar();break;case ′=′: PopStack(&operator,&x); ch=getchar();break;4数据结构课程设计报告(2012)case ′>′: PopStack(&operator, &op); PopStack(&operand,&b);PopStack(&operand, &a);v=Execute(a,op,b);PushStack(&operand,v); break;}}v=GetTop(operand);return(v); }为了处理方便,编译程序常把中缀表达式首先转换成等价的后缀表达式,后缀表达式的运算符在运算对象之后。
在后缀表达式中,不再引入括号,所有的计算按运算符出现的顺序,严格从左向右进行,而不用再考虑运算规则和级别。
中缀表达式“(a+b*c)-d/e”的后缀表达式为:“abc*+de/-”。
3. 后缀表达式求值:计算一个后缀表达式,算法上比计算一个中缀表达式简单的多。
这是因为表达式中即无括号又无优先级的约束。
具体做法:只使用一个对象栈,当从左向右扫描表达式时,每遇到一个操作数就送入栈中保存,每遇到一个运算符就从栈中取出两个操作数进行当前的计算,然后把结果再入栈,直到整个表达式结束,这时送入栈顶的值就是结果。
下面是后缀表达式求值的算法,在下面的算法中假设,每个表达式是合乎语法的,并且假设后缀表达式已被存入一个足够大的字符数组A中,且以‘#’为结束字符,为了简化问题,限定运算数的位数仅为一位且忽略了数字字符串与相对应的数据之间的转换问题。
double calcul_exp(char *A) /*本函数返回由后缀表达式A表示的表达式运算结果*/{ SeqStarck s;ch=*A++ ; InitStack(s);while(ch!= ’#’ ){ if(ch!=运算符) PushStack(s, ch);else{ PopStack(s, &a);PopStack(s, &b); /*取出两个运算量*/switch(ch){ case ch==’+’: c=a+b; break ;case ch==’-’: c=a-b; break ;case ch==’*’: c=a*b; break ;case ch==’/ ’: c=a/b; break ;case ch==’%’:c=a%b; break ;}PushStack (s, c) ;}ch=*A++ ;}PopStack(s, result) ;5表达式求值return result ;}4. 中缀表达式转换成后缀表达式 :将中缀表达式转化为后缀表达式和前述对中缀表达式求值的方法完全类似,但只需要运算符栈,遇到运算对象时直接放后缀表达式的存储区,假设中缀表达式本身合法且在字符数组A中,转换后的后缀表达式存储在字符数组B中。