数据结构课程设计表达式求值【完整版】
(完整word版)数据结构表达式求值实验报告

《数据结构》课程设计报告书题目: 表达式求值系别:计算机科学与信息系学号:学生姓名:指导教师:完成日期:目录➢1.前言➢2.概要设计2。
1 数据结构设计2.2 算法设计2.3 ADT描述2。
4 功能模块分析➢3。
详细设计3.1 数据存储结构设计3.2主要算法流程图(或算法代码)➢4.软件测试➢5。
总结➢附录1.前言在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行.因而在程序设计时,借助栈实现。
算法输入:一个算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)。
为简化,规定操作数只能为正整数,操作符为+、-*、/,用#表示结束。
算法输出:表达式运算结果。
算法要点:设置运算符栈和运算数栈辅助分析算符优先关系。
在读入表达式的字符序列的同时,完成运算符和运算数的识别处理,以及相应运算。
2.概要设计2.1 数据结构设计任何一个表达式都是由操作符,运算符和界限符组成的。
我们分别用顺序栈来寄存表达式的操作数和运算符.栈是限定于紧仅在表尾进行插入或删除操作的线性表。
顺序栈的存储结构是利用一组连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置,base为栈底指针,在顺序栈中,它始终指向栈底,即top=base可作为栈空的标记,每当插入新的栈顶元素时,指针top增1,删除栈顶元素时,指针top减1。
2.2 算法设计为了实现算符优先算法。
可以使用两个工作栈。
一个称为OPTR ,用以寄存运算符,另一个称做OPND ,用以寄存操作数或运算结果。
1。
首先置操作数栈为空栈,表达式起始符”#"为运算符栈的栈底元素;2.依次读入表达式,若是操作符即进OPND 栈,若是运算符则和OPTR 栈的栈顶运算符比较优先权后作相应的操作,直至整个表达式求值完毕(即OPTR 栈的栈顶元素和当前读入的字符均为"#")。
数据结构课程设计- 算术表达式求值

课程设计报告课程名称数据结构课程设计题目算术表达式求值指导教师设计起始日期 4.18~4.25学院计算机学院系别计算机科学与工程学生姓名班级/学号成绩一、需求分析设计一个算术表达式四则运算的程序,要求完成包括加、减、乘、除运算,包含括号的基本整数表达式的运算。
在这里运算数可以1位长度,也可以多位长度。
在运算之后输出的正确运算结果,输入表达式后演示在求值中运算数栈内的栈顶数据变化过程,最后得到运算结果。
(1)输入:3*(7-2)(2)输出:数据栈栈顶元素:3,7,2,7,5,3,15结果:15(3)自选数据二、概要设计1、使用栈的数据结构表示数据的存储。
2、设计算法将中缀表达式转换成后缀表达式,用栈的数据结构实现表达式的运算。
3、把中缀表达式转换为后缀表达式算法的基本思路是从头到尾地扫描中缀表达式中的每个字符,对于不同类型的字符按不情况进行处理。
三、详细设计数据结构:字符类型栈/* 定义字符类型栈*/typedef struct{char stackname[20];char *base;char *top;} Stack;算法:将中缀表达式转换为后缀表达式void Change(char* s1, char* s2)// 将字符串s1中的中缀表达式转换为存于字符串s2中的后缀表达式{Stack R; // 定义用于暂存运算符的栈InitStack(R); // 初始化栈Push(R,'#'); // 给栈底放入’#’字符,它具有最低优先级0int i,j;i=0; // 用于指示扫描s1串中字符的位置,初值为0j=0; // 用于指示s2串中待存字符的位置,初值为0char ch=s1[i]; // ch保存s1串中扫描到的字符,初值为第一个字符while( ch!='#'){ // 顺序处理中缀表达式中的每个字符if(ch==' ')// 对于空格字符不做任何处理,顺序读取下一个字符ch=s1[++i];else if(ch=='('){ // 对于左括号,直接进栈Push(R,ch);ch=s1[++i];}else if(ch==')'){ // 对于右括号,使括号内的仍停留在栈中的运算符依次// 出栈并写入到s2中while(Peek(R)!='(')s2[j++]=Pop(R);Pop(R); // 删除栈顶的左括号ch=s1[++i];}else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'){ // 对于四则运算符,使暂存在栈中的不低于ch优先级// 的运算符依次出栈并写入到s2中char w=Peek(R);while(Precedence(w)>=Precedence(ch)){ // Precedence(w)函数返回运算符形参的优先级s2[j++]=w;Pop(R); w=Peek(R); }}四、调试分析调试:在设计过程中出现程序不能运行,发现不能找到结束标识符,因此在设计的时候需要人为动态添加结束标识符‘#’,顺利运行算法时间和空间分析:算法的运行时间主要花在while循环上,它从头到尾扫描后缀表达式中的每一个数据(每个操作数或运算符均为一个数据),若后缀表达式由n个数据组成,则此算法的时间复杂度为O(n)。
数据结构(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磅。
一级标题靠左,加粗。
二级大标题靠左,不加粗。
数据结构表达式求值(可以求小数与多位数)

//栈顶压入一个数
S.top++; } char PopOPTR(SqStackOPTR &S,char &e){ --S.top; e=*S.top; return e; } float PopOPND(SqStackOPND &S,float &e){ --S.top; e=*S.top; return e; } Status GetTopOPTR(SqStackOPTR &S,char &e){ e=*(S.top-1); return e; } float GetTopOPND(SqStackOPND &S,float &e){ e=*(S.top-1); return e; } unsigned char 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)。
数据结构课程设计-表达式求值【完整版】

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

模块
• 各个模块的主要功能: *Push(SC *s,char c):把字符压栈 *Push(SF *s,float f):把数值压栈 *Pop(SC *s):把字符退栈 *Pop(SF *s):把数值退栈 Operate(a,theta,b):根据theta对a和b进行'+' 、'-' 、'*' 、'/' 、'^'操作 In(Test,*TestOp):若Test为运算符则返回true,否则返回false ReturnOpOrd(op,*TestOp):若Test为运算符,则返回此运算符在数组中的下标 precede(Aop,Bop):根据运算符优先级表返回Aop与Bop之间的优先级 EvaluateExpression(*MyExpression):用算符优先法对算术表达式求值
c++;
后ቤተ መጻሕፍቲ ባይዱ表达式的计算机求值
• 与前缀表达式类似,只是顺序是从左至右
• 从左至右扫描表达式, • 遇到数字,将数字压入栈; • 遇到运算符,弹出栈顶的两个数,用运算符对它们做相应的计算
(次顶元素 operate with 栈顶元素),并将结果入栈; • 重复上述过程直到表达式最右端,最后运算得出的值即为表达式
SC *Push(SC *s,char c)
//SC类型的指针Push,返回p {
SC *p=(SC*)malloc(sizeof(SC));
p->c=c; p->next=s;
return p;
}
SF *Push(SF *s,float f) //SF类型的指针Push,返回p { SF *p=(SF*)malloc(sizeof(SF)); p->f=f; p->next=s; return p; }
数据结构课程设计四则运算表达式求值(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 }。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
XXXXXX大学《数据结构》课程设计报告班级:学号:姓名:指导老师:目录一算术表达式求值一、需求分析二、程序的主要功能三、程序运行平台四、数据结构五、算法及时间复杂度六、测试用例七、程序源代码二感想体会与总结算术表达式求值一、需求分析一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。
假设操作数是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。
引入表达式起始、结束符是为了方便。
编程利用“算符优先法”求算术表达式的值。
二、程序的主要功能(1)从键盘读入一个合法的算术表达式,输出正确的结果。
(2)显示输入序列和栈的变化过程。
三、程序运行平台Visual C++ 6.0版本四、数据结构本程序的数据结构为栈。
(1)运算符栈部分:struct SqStack //定义栈{char *base; //栈底指针char *top; //栈顶指针int stacksize; //栈的长度};int InitStack (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的栈顶元素,并返回OKreturn OK;}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的栈顶元素,并返回OKreturn 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; //栈的长度};int InitStackn (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"); //栈为空的时候返回ERRORreturn ERROR;}elsee=*(s.top-1); //栈不为空的时候,用e作返回值,返回S的栈顶元素,并返回OKreturn OK;}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; //栈顶指针变化return OK;}int Popn(SqStackn &s,int &e) //数栈出栈{if (s.top==s.base){printf(" 运算符栈为空!\n"); //栈为空栈的视时候,返回ERRORreturn ERROR;}else{e=*--s.top; //栈不空的时候,则删除S的栈顶元素,用e返回其值,并返回OKreturn OK;}}int StackTraversen(SqStackn &s) //数栈遍历{int *t;t=s.base ;if (s.top==s.base){printf(" 运算数栈为空!\n"); //栈为空栈的时候返回ERRORreturn ERROR;}while(t!=s.top){printf(" %d",*t); //栈不为空的时候依次输出t++;}return ERROR;}五、算法及时间复杂度1、算法:建立两个不同类型的空栈,先把一个‘# ’压入运算符栈。
输入一个算术表达式的字符串(以‘#’结束),从第一个字符依次向后读,把读取的数字放入数字栈,运算符放入运算符栈。
判断新读取的运算符和运算符栈顶得运算符号的优先级,以便确定是运算还是把运算符压入运算符栈。
最后两个‘#’遇到一起则运算结束。
数字栈顶的数字就是要求的结果。
2、时间复杂度:O(n)数据压缩存储栈,其操作主要有:建立栈int Push(SeqStack *S, char x)入栈int Pop(SeqStack *S, char x)出栈。
以上各操作运算的平均时间复杂度为O(n),其主要时间是耗费在输入操作。
六、测试用例如图所示。
最终结果如图所示:七、源代码/*********************************************************************************************** ***第七题算术表达式求值[问题描述]一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。
假设操作数是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。
引入表达式起始、结束符是为了方便。
编程利用“算符优先法”求算术表达式的值。
[基本要求](1)从键盘读入一个合法的算术表达式,输出正确的结果。
(2)显示输入序列和栈的变化过程。
************************************************************************************************ ***/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include <conio.h>#include <ctype.h>#define OK 1#define ERROR 0#define STACK_INIT_SIZE 100//#define STACKINCREMENT 10//========================================================// 以下定义两种栈,分别存放运算符和数字//========================================================//*******************运算符栈部分*************************struct SqStack //定义栈{char *base; //栈底指针char *top; //栈顶指针int stacksize; //栈的长度};int InitStack (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的栈顶元素,并返回OKreturn OK;}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的栈顶元素,并返回OKreturn 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;}//**********************数字栈部分***************************struct SqStackn //定义数栈{int *base; //栈底指针int *top; //栈顶指针int stacksize; //栈的长度};int InitStackn (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"); //栈为空的时候返回ERRORreturn ERROR;}elsee=*(s.top-1); //栈不为空的时候,用e作返回值,返回S的栈顶元素,并返回OKreturn OK;}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; //栈顶指针变化return OK;}int Popn(SqStackn &s,int &e) //数栈出栈{if (s.top==s.base){printf(" 运算符栈为空!\n"); //栈为空栈的视时候,返回ERRORreturn ERROR;}else{e=*--s.top; //栈不空的时候,则删除S的栈顶元素,用e返回其值,并返回OKreturn OK;}}int StackTraversen(SqStackn &s) //数栈遍历{int *t;t=s.base ;if (s.top==s.base){printf(" 运算数栈为空!\n"); //栈为空栈的时候返回ERRORreturn ERROR;}while(t!=s.top){printf(" %d",*t); //栈不为空的时候依次输出t++;}return ERROR;}//========================================================// 以下定义函数//========================================================int Isoperator(char ch) //判断是否为运算符,分别将运算符和数字进入不同的栈{switch (ch){case '+':case '-':case '*':case '/':case '(':case ')':case '#':return 1;default:return 0;}}int Operate(int a, char op, int b) //运算操作{int result;switch(op){case '+':result=a+b;break;case '-':result=a-b;break;case '*':result=a*b;break;case '/':result=a/b;break;}return result;}char Precede(char ch1, char ch2) //运算符优先级的比较{char p;switch(ch1){case '+':case '-':if (ch2=='+'||ch2=='-'||ch2==')'||ch2=='#')p = '>'; //ch1运算符的优先级小于ch2运算符elsep = '<';break;case '*':case '/':if (ch2 == '(')p = '<';elsep = '>';break;case '(':if (ch2 == ')')p = '=';else if (ch2 == '#'){printf(" 表达式错误!运算符不匹配!\n") ;exit(0);}elsep = '<';break ;case ')':if (ch2 == '('){printf(" 表达式错误!运算符不匹配!\n") ;exit(0);}elsep = '>';break ;case '#':if (ch2 == ')'){printf(" 表达式错误!运算符不匹配!\n") ;exit(0);}else if (ch2 == '#')p = '=';elsep='<';break;}return p;}//======================================================== // 以下是求值过程//========================================================int EvaluateExpression() //参考书p53算法3.4{int a, b, temp, answer;char ch,op,e;char *str;int j = 0;SqStackn OPND; //OPND为运算数字栈SqStack OPTR; //OPTR为运算符栈InitStack(OPTR);Push(OPTR,'#'); //,所以此栈底是'#',因为运算符栈以'#'作为结束标志InitStackn(OPND);// printf("\n\n按任意键开始求解:\n\n");// ch=getch();printf("\n请输入表达式并以'#'结束:\n");str =(char*)malloc(50*sizeof(char));gets(str);ch=str[j]; //ch是字符型的,而e是整型的整数j++;GetTop(OPTR,e); //e为栈顶元素返回值while (ch!='#' || e!='#'){if (!Isoperator(ch)) //遇到数字,转换成十进制并计算{temp=ch-'0'; //将字符转换为十进制数ch=str[j];j++;while(!Isoperator(ch)){temp=temp*10 + ch-'0'; //将逐个读入运算数的各位转化为十进制数ch=str[j];j++;}Pushn(OPND,temp);}else if (Isoperator(ch)) //判断是否是运算符,不是运算符则进栈switch (Precede(e,ch)){case '<' : Push(OPTR,ch); // 栈顶元素优先权低ch = str[j++];printf("\n\n 运算符栈为:\n"); //输出栈,显示栈的变化StackTraverse(OPTR);printf("\n 运算数栈为:\n");StackTraversen(OPND);break;case '=' : Pop(OPTR,op); // 脱括号并接收下一字符ch = str[j++] ;printf("\n\n 运算符栈为:\n");StackTraverse(OPTR);printf("\n 数栈为:\n");StackTraversen(OPND);break;case '>' : Pop(OPTR,op); //弹出最上面两个,并运算,把结果进栈Popn(OPND,b);Popn(OPND,a);Pushn(OPND,Operate(a,op,b));printf("\n\n 运算符栈为:\n");StackTraverse(OPTR);printf("\n 数栈为:\n");StackTraversen(OPND);}else{printf("您的输入有问题,请检查重新输入!");exit(0);}GetTop(OPTR,e); //取出运算符栈最上面元素是否是'#' } //whileGetTopn(OPND,answer); //已输出。