《数据结构课程设计》表达式求值实验报告
(完整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 栈的栈顶元素和当前读入的字符均为"#")。
数据结构表达式求值实验报告
竭诚为您提供优质文档/双击可除数据结构表达式求值实验报告篇一:数据结构实验二——算术表达式求值实验报告《数据结构与数据库》实验报告实验题目算术表达式求值学院:化学与材料科学学院专业班级: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,后缀用0),在输入一个中缀表达式,输入数的范围为int型,此时,程序将计算出表达式的结果。
2、输出的形式:当按照程序要求选择了1或0之后,再输入表达式;如果选择的是1,则程序将自动运算出表达式结果;如果之前选择的是0,则程序将现将中缀表达式转化为后缀表达式并计算出结果。
3、程序所能达到的功能:本程序能计算出含+、-、*、/、(、)等运算符的简单运算。
4、测试数据:输入一个表达式,如果你之前选择的是“中缀表达式”,那么输入5*(4-2)#,那么输出结果是10;如果之前选择的是“后缀表达式”,那么输入5*(4-2)#,那么他将先转换成后缀表达式5 4 2 - * #,再输出结果10。
如果输入表达式没有结束标示符#,如5*(4-2),那将不会输出任何结果,或出现错误结果。
(二) 概要设计为了实现上述操作,应以栈为存储结构。
1.基本操作:(1). int GetTop(SqStack *s)初始条件:栈存在;操作结果:若栈为空,则返回s的栈顶元素;否则返回ERROR。
(2).void Push(SqStack *s,int e)初始条件:栈存在;操作结果:插入e为新的栈顶元素。
(3).int Pop(SqStack *s)初始条件:栈存在;操作结果:若栈不空,则删除之,并返回其值;否则返回REEOR。
(4).void InitStack(SqStack *s)初始条件:栈存在;操作结果:置栈为空。
(5).int Empty(SqStack *s)初始条件:栈存在;操作结果:判定s是否为空栈。
(6).int Operate(int a,char theta, int b)初始条件:操作数a和b存在,且theta是+、-、*、/四则运算;操作结果:返回a与b间theta运算的结果。
(7).int In(char s,char* TestOp)初始条件:s为待判断字符,TestOp为已知的算符集合;操作结果:s为算符集合中的元素则返回1,否则返回0.(8).int ReturnOpOrd(char op,char* TestOp)初始条件:op为待确定运算符,TestOp为已知的算符集合;操作结果:确定运算符类型。
数据结构表达式求值实验报告
数据结构表达式求值实验报告数据结构表达式求值实验报告第一章引言数据结构是计算机科学中重要的基础知识之一,它研究的是数据在计算机中的存储和组织方式,以及基于这些方式进行操作和运算的算法。
表达式求值是数据结构中一个重要的应用场景,它涉及到从一个给定的表达式中计算出最终结果的过程。
本实验旨在通过实际编程实践,掌握表达式求值的算法和数据结构的应用。
第二章实验目的1.理解表达式的概念。
2.熟悉常见表达式求值算法。
3.掌握栈的基本操作。
4.实现一个表达式求值的程序。
第三章实验内容1.表达式的定义:________表达式是由运算符和运算数组成的字符串,它代表了一种计算规则。
2.表达式的分类:________根据运算符的位置和计算顺序,表达式可以分为前缀表达式、中缀表达式和后缀表达式。
3.表达式求值的算法:________1. 前缀表达式求值算法:________1) 创建一个空栈。
2) 从右往左遍历前缀表达式。
3) 如果当前字符是运算符,则将栈顶的两个元素出栈,进行相应的运算,将结果入栈。
4) 如果当前字符是运算数,则将其转化为整数形式,并入栈。
5) 最终栈内只剩下一个元素,即为表达式的求值结果。
2. 中缀表达式求值算法:________1) 将中缀表达式转化为后缀表达式。
2) 创建一个空栈。
3) 从左往右遍历后缀表达式。
4) 如果当前字符是运算符,则将栈顶的两个元素出栈,进行相应的运算,将结果入栈。
5) 如果当前字符是运算数,则将其转化为整数形式,并入栈。
6) 最终栈内只剩下一个元素,即为表达式的求值结果。
3. 后缀表达式求值算法:________1) 创建一个空栈。
2) 从左往右遍历后缀表达式。
3) 如果当前字符是运算符,则将栈顶的两个元素出栈,进行相应的运算,将结果入栈。
4) 如果当前字符是运算数,则将其转化为整数形式,并入栈。
5) 最终栈内只剩下一个元素,即为表达式的求值结果。
4.实验代码实现:________根据算法描述,使用编程语言实现一个表达式求值的程序。
数据结构课程设计-表达式求值【完整版】
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)
{
数据结构表达式求值(中缀)实验报告
数据结构表达式求值(中缀)实验报告题目名称表达式求值学号姓名指导教师日期一1. 问题描述:在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行,在程序设计时,借助栈实现。
2. 表达式求值这个程序,主要利用栈和数组,把运算的先后步骤进行分析并实现简单的运算,以字符列的形式从终端输入语法的正确的、不含变量的整数表达式。
利用已知的算符优先关系,实现对算术四则运算的求值,在求值中运用栈、运算栈、输入字符和主要操作的变化过程。
该程序相当于一个简单的计算机计算程序,只进行简单的加减乘除和带括号的四则运算。
1、基本思想(中缀表达式求值)要把一个表达式翻译成正确求值的一个机器指令序列,或者直接对表达式求值,首先要能够正确解释表达式,要了解算术四则运算的规则即:(1)先乘除后加减;(2)从左到右计算;(3)先括号内,后括号外。
下表定义的运算符之间的关系:b + - * / () # a+ > > < < < > > _ > > < < < > > * > > > > < > > / > > > > < > > ( < < < < < = ) > > > > > > # < < < < < =为了实现运算符有限算法,在程序中使用了两个工作栈。
分别是:运算符栈OPTR,操作数栈OPND.基本思想:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;(2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈得栈顶运算符比较优先级后作相应操作。
数据结构表达式求值完整篇(含实验报告)
&s,SElemType_OPND&e); //出栈
/*
#i nclude "common .h"
#include "Sqstack.h"
#in clude "other.h"
//
void OPTR_I ni tStack(Sqstack_OPTR &s)
3前面的都听简单的,就是 小数编写这块想了很久,
定义了low做判定符号的标志。如果在运算符后输入负号则low=-1(将p入栈时入栈
的是p*low),继续输入ch
总结:
我觉得写的好的地方在于定义了flag,low分别作为小数入栈和负号与减号区别的条
件。第一次写这么长的代码,还有就是将输入的字符再转到小数这段代码可以留着很有 用。开始考虑的大整数想麻烦了,直接用double难度降低了很多
//取操作数的栈顶元素
voidOPTR_Push(Sqstack_OPTR
&s,SElemType_OPTR e);//入栈
voidOPND_Push(Sqstack_OPND
&s,SElemType_OPND e); //入栈
voidOPTR_Pop(Sqstack_OPTR
&s,SEIemType_OPTR&e); //出栈
//栈基本操作的函数声明
void OPTR_lnitStack(Sqstack_OPTR &s);
//运算符栈初始化
void OPBiblioteka D_InitStack(Sqstack_OPND &s);
//操作数栈初始化
数据结构课程设计_实验报告(一)表达式求值(计算器)
数据结构课程设计实验报告起止时间:2015.12.28-2015.12.311、输入:tan452、输出:13、执行结果::设计过程中遇到的问题及解决办法:问题:算数表达式以字符串输入,操作数和操作符的提取;解决办法:两两操作符之间如有数字将中间的数字提取强制转换成double型;参考文献:(在设计中参考的书籍、网站等资料)1. 朱振元,《数据结构——C++语言描述》,清华大学出版社,2008年,页码:2. /detail/gszhouyi/738777指导老师评议:成绩评定:指导教师签名:附件:(程序源代码)#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#define N 100#define pai 3.1415926typedef struct yxj{char operat;int rank;}yxj;typedef struct str{char data[N];}zs;void sjhs(void){char s[10],a[10];double y,x;printf("请输入(sin cos tan 角度制)表达式:\n");scanf("%s",s);if(strstr(s,"sin")!=0){int i=0,j=0;while(s[i]!='\0'){if(s[i]>='0'&&s[i]<='9')s[j++]=s[i];i++;}s[j]='\0';x=atof(s);y=sin(x*pai/180);}else if(strstr(s,"cos")!=0){int i=0,j=0;while(s[i]!='\0'){if(s[i]>='0'&&s[i]<='9')s[j++]=s[i];i++;}s[j]='\0';x=atof(s);y=cos(x*pai/180);}else if(strstr(s,"tan")!=0){int i=0,j=0;while(s[i]!='\0'){if(s[i]>='0'&&s[i]<='9')s[j++]=s[i];i++;}s[j]='\0';x=atof(s);y=tan(x*pai/180);}else{printf("格式错误\n");return;}printf("%lf\n",y);printf("*****1、继续*****\n");printf("*****0、返回上一层*****\n");scanf("%s",a);if(strcmp(a,"0")==0)return;else if(strcmp(a,"1")==0)sjhs();elseprintf("没有该选项\n");}void szys(yxj mark[]){yxj os[N];char a[10];char ch;double ns[N];zs zhan[20];int numb[N];int Len,p=0,q=1,i,o=1,n=0;char data[N];os[0]=mark[0];ns[0]=0;printf("请输入算术(+ - * / ^)表达式(以= 结束):\n");scanf("%s",data);if(strcmp(data,"+")==0||strcmp(data,"-")==0||strcmp(data,"*")==0||strcmp(data,"/")==0 ||strcmp(data,"^")==0||strcmp(data,"=")==0){printf("格式错误\n");return;}Len=strlen(data);numb[0]=0;for(i=0;i<20;i++)zhan[i].data[0]='\0';for(i=0;i<Len;i++){int t=0;if((data[i]=='^'||data[i]=='+'||data[i]=='-'||data[i]=='*'||data[i]=='/'||data[i]=='('||data[i]==')'||data[i]=='=')) {int j,k=0;if((data[i]=='='||data[i]=='^'||data[i]=='+'||data[i]=='-'||data[i]=='*'||data[i]=='/')&&(data[i-1]=='^'||data[i-1]=='+'||data[i-1]=='-'||data[i-1]=='*'||data[i-1]=='/')){printf("格式错误\n");return;}numb[q++]=i;while(zhan[(p+k)/2].data[0]!='\0'){k++;}for(j=numb[q-2];j<numb[q-1];j++)if(data[j]>='0'&&data[j]<='9'||data[j]=='.')zhan[(p+k)/2].data[t++]=data[j];zhan[(p+k)/2].data[t]='\0';if(zhan[(p+k)/2].data[0]!='\0')ns[n++]=atof(zhan[(p+k)/2].data);p++;for(j=0;j<8;j++)if(mark[j].operat==data[i])break;while(1){.if(mark[j].operat=='('){os[o++]=mark[j];break;}else if(mark[j].rank>os[o-1].rank&&mark[j].operat!='(') {os[o++]=mark[j];break;}else{double numb1,numb2,numb;switch(ch=os[--o].operat){case '+':{numb1=ns[--n];numb2=ns[--n];numb=numb1+numb2;ns[n++]=numb;break;}case '-':{numb1=ns[--n];numb2=ns[--n];numb=numb2-numb1;ns[n++]=numb;break;}case '*':{numb1=ns[--n];numb2=ns[--n];numb=numb2*numb1;ns[n++]=numb;break;}case '/':{numb1=ns[--n];numb2=ns[--n];if(numb1==0){printf("无效操作\n");return;}else{numb=numb2/numb1;ns[n++]=numb;}break;}case '^':{numb1=ns[--n];numb2=ns[--n];numb=pow(numb2,numb1);ns[n++]=numb;break;}}}}}else if(data[i]>='0'&&data[i]<='9');else if(data[i]=='.');else{printf("格式错误,请重新输入:\n");szys(mark);break;}}printf("%lf\n",ns[0]);printf("*****1、继续*****\n");printf("*****0、返回上一层*****\n");scanf("%s",&a);if(strcmp(a,"0")==0)return;else if(strcmp(a,"1")==0)szys(mark);elseprintf("没有该选项\n");}int main (){yxj mark[9];mark[0].operat='#';mark[0].rank=-1;mark[1].operat='+';mark[1].rank=1;mark[2].operat='-';mark[2].rank=1;mark[3].operat='*';mark[3].rank=2;mark[4].operat='/';mark[4].rank=2;mark[5].operat='(';mark[5].rank=-1;mark[6].operat=')';mark[6].rank=-1;mark[7].operat='=';mark[7].rank=0;mark[8].operat='^';mark[8].rank=3;while(1){char i[10];printf("*****1、四则运算计算器*****\n");printf("*****2、三角函数计算器*****\n");printf("*****0、退出*****\n");scanf("%s",&i);if(strcmp(i,"0")==0)break;else if(strcmp(i,"1")==0)szys(mark);else if(strcmp(i,"2")==0)sjhs();elseprintf("没有该选项\n");}}。
数据结构表达式求值实验报告
数据结构表达式求值实验报告数据结构表达式求值实验报告⒈引言本实验旨在研究和实现数据结构中表达式求值的算法。
表达式求值是计算机科学中常见的问题,对于计算机程序的正确性和性能具有重要影响。
本报告将详细介绍实验设计、实验步骤、实验结果及分析,并对实验过程中遇到的问题进行讨论。
⒉实验设计⑴实验目的本实验的目的是实现一个可以对常见的算术表达式进行求值的算法,包括支持基本的加减乘除运算符和括号。
⑵实验环境●操作系统:Windows 10●开发语言:C++●开发工具:Visual Studio 2019⑶数据结构设计为了实现表达式求值的算法,我们需要设计适当的数据结构来存储和处理表达式。
本实验中,我们选择使用栈来实现表达式求值。
●表达式栈:用于存储操作数和运算符。
●运算符栈:用于存储运算符。
⑷算法设计表达式求值的算法可以分为以下几个步骤:●遍历表达式,逐个处理操作数和运算符:●如果是操作数,入表达式栈。
●如果是运算符,与运算符栈栈顶元素进行比较,根据优先级决定如何处理。
●当表达式遍历完成后,依次处理剩余的运算符。
●最终表达式栈中的元素即为求值结果。
⒊实验步骤⑴数据结构实现根据设计,我们首先实现表达式栈和运算符栈的数据结构,包括入栈、出栈等操作。
⑵表达式输入与预处理用户输入待求值的表达式,进行预处理,去除空格、验证表达式的合法性等。
⑶表达式求值算法实现根据前述的算法设计,实现表达式求值的算法,利用表达式栈和运算符栈来处理表达式。
⑷测试与结果分析对于不同的测试用例,进行表达式求值的测试,并分析结果的正确性和性能。
⒋实验结果与分析经过实验测试,我们得到了表达式求值的结果。
结果显示,我们的算法能够正确地求得表达式的值,而且性能良好。
⒌讨论与总结在实验过程中,我们遇到了一些问题,并进行了讨论和解决。
通过这个实验,我们更加深入地理解了表达式求值的算法,并对数据结构的应用有了更清晰的认识。
附件:无法律名词及注释:●无。
数据结构 四则运算表达式求值 实验四报告
为后缀表达式。
(3) 计算模块:计算后缀表达式的值。
(4) 输出模块:输出后缀表达式及其计算结果。
三、详细设计
物理数据类型
因为表达式由用户输入,存储操作符和操作数的栈长度不能确定,所以使用链式堆栈存
储这些变量。
堆栈基本操作如下:
bool push(const Elem& item) //压栈
{
top=new link<Elem>(item,top);
表达式。
运算时,运算符栈顶弹栈,然后获取操作数栈顶和次栈顶的值进行运算,把运算结果创
建一个叶子结点保存,把结点压回操作数栈中。如果操作数栈或运算符栈不为空时,继续进
行运算操作。最后操作数栈中的值,就是运算结果。
程序的流程
(1) 输入模块:输入把原始的中缀表达式的操作数和操作字符存储为一个字符串。 (2) 处理模块:把字符串逐个分解,调整各项字符的顺序,分解的中缀表达式转换
EvalExpr(ch[i],S); //弹栈,运算部分
i++;
}
}
if(S.length()==1)
S.pop(result);
}
(2)、 转换实数
int EvalValue(char* ch,Stack<double> &S)
{
int i=0;
double result=0;
char a;
a=ch[i];
}
bool topValue(Elem& it) const //获取栈顶的值
{
if(size==0) return false;
it=top->elem;
return true;
表达式求值数据结构实训报告
数据结构实训总结报告题目:表达式求值学生姓名:学生学号:专业班级:指导老师:目录1.课题分析 .....................................................................1.1需求分析..............................................................1. 2设计要求............................................................2.总体设计.......................................................................2.1主程序的流程.....................................................3.详细设计(步骤及代码实现) ...................................3. 1判断运算符优先级..............................................3. 2中缀表达式转后缀表达式..................................3. 3后缀表达式求值.................................................. 4.测试结果 .................................................................... 5.心得体会 .................................................................... 6.参考文献 ....................................................................1.课题分析1.1需求分析(1)栈“后进先出”的特点。
数据结构表达式求值实验报告
实验二表达式求值
实验内容:
用算符优先法设计一个具有加、减、乘、除四功能的计算程序。
实验目的与要求:
掌握栈的数据结构和基本操作。
实验原理:
1.表达式是由操作数,运算符和界限符组成。
2.实现算符优先算法,实用两个工作栈。
一个叫OPTR,用以寄存运算符;一个叫OPND,用以寄存操作数或运算结果。
3.算法的基本思路:
(1)首先置操作数栈为空栈,表达式起始符#作为运算符栈的栈底元素;
(2) 依次读入表达式中的每个字符,通过运算符判断函数In()使操作数进OPND 栈;
(3)通过函数Precede()将运算符与OPTR栈的栈底运算符比较出优先权,若栈顶元素优先权低则输入下个操作数到OPND,若两优先权相等,脱号并接受下一个字符,若栈顶元素优先高,退栈并将运算结果(通过函数Operate()运算)入栈。
循环上述操作直到表达式求值结束。
(4)返回运算结果。
4.所用的函数及作用:
InitStack():构造一个空栈
Push():插入元素进栈
GetTop():返回栈顶元素
Precede():运算符优先权进行判断
Pop():元素出栈
Operate():运算操作数
5. 测试结果与分析
上述程序在Visual C++ 6.0环境下加以实现。
经过多次测试,程序运行正确。
运行结果。
如图所示:
6. 收获与体会
通过这次课程设计:
1.我又进一步巩固了C语言的基础,尤其是栈。
2.算法中需要建很多的函数,队提高了自己的编程能力有帮助,
3.程序不够简洁,还有待改进,功能还有待更完善。
数据结构实验报告——四则运算表达式求值
数据结构实验报告——四则运算表达式求值实验五四则运算表达式求值一.问题描述:四则运算表达式求值,将四则运算表达式用中缀表达式,然后转换为后缀表达式,并计算结果。
二.基本要求:使用二叉树来实现。
三.实现提示:利用二叉树后序遍历来实现表达式的转换,同时可以使用实验二的结果来求解后缀表达式的值。
输入输出格式:输入:在字符界面上输入一个中缀表达式,回车表示结束。
输出:如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。
测试实例:输入:21+23* (12-6 )输出:21 23 12 6 -*+四.设计概要用二叉树表示表达式:若表达式为数或简单变量,则相应二叉树中仅有一个根结点,其数据域存放该表达式信息若表达式= (第一操作数)(运算符)(第二操作数),则相应的二叉树中以左子树表示第一操作数,右子树表示第二操作数,根结点的数据域存放运算符(若为一元算符,则左子树空)。
操作数本身又为表达式.后缀遍历二叉树码实现和静态检查上机调试及测试数据的调试五.源程序:#include#include#include#include#include#include#define STACK_INIT_SIZE 100#define DATA_SIZE 10#define STACKINCREMENT 10#define OK 1#define TRUE 1#define FALSE 0#define ERROR 0#define OVERFLOW -2using namespace std;typedef float SElemtype;typedef int Status;typedef char * TElemType;typedef struct BiTNode {TElemType data;int len; //data字符串中字符的个数struct BiTNode * lchild, * rchild;}BiTNode, *BiTree;typedef struct{SElemtype *base;SElemtype *top;int stacksize;} SqStack;Status IsDigital(char ch)if(ch>='0'&&ch<='9'){return 1; //是数字字母}return 0; //不是数字字母}int CrtNode(stack &PTR, char *c){BiTNode * T;int i=0;T = (BiTNode *)malloc(sizeof(BiTNode));T->data = (char *)malloc(DATA_SIZE*sizeof(char));while(IsDigital(c[i])){T->data [i] = c[i];i++;}T->len = i;T->lchild = T->rchild = NULL;PTR.push (T);return i;}void CrtSubTree(stack &PTR, char c){BiTNode * T;T = (BiTNode *)malloc(sizeof(BiTNode));T->data = (char *)malloc(DATA_SIZE*sizeof(char));T->data [0] = c;T->len = 1;T->rchild = PTR.top(); //先右子树,否则运算次序反了PTR.pop ();T->lchild = PTR.top();PTR.pop ();PTR.push (T);}char symbol[5][5]={{'>', '>', '<', '<', '>'}, //符号优先级{'>', '>', '<', '<', '>'},{'>', '>', '>', '>', '>'},{'>', '>', '>', '>', '>'},{'<', '<', '<', '<', '='}};int sym2num(char s) //返回符号对应优先级矩阵位置{switch(s){case '+': return 0; break;case '-': return 1; break;case '*': return 2; break;case '/': return 3; break;case '#': return 4; break;}}char Precede(char a, char b) //返回符号优先级{return(symbol[sym2num(a)][sym2num(b)]);void CrtExptree(BiTree &T, char exp[]){//根据字符串exp的内容构建表达式树Tstack PTR;//存放表达式树中的节点指针stack OPTR;//存放操作符char op;int i=0;OPTR.push ('#');op = OPTR.top();while( !((exp[i]=='#') && (OPTR.top()=='#')) ) //与{ if (IsDigital(exp[i])){//建立叶子节点并入栈PTRi+=CrtNode(PTR, &exp[i]);}else if (exp[i] == ' ')i++;else{switch (exp[i]){case '(': {OPTR.push (exp[i]);i++;break;}case ')': {op = OPTR.top (); OPTR.pop ();while(op!='('){CrtSubTree(PTR, op);op = OPTR.top (); OPTR.pop ();}//end whilei++;break;}default: //exp[i]是+ - * /while(! OPTR.empty ()){op = OPTR.top ();if (Precede(op, exp[i])=='>'){CrtSubTree(PTR, op);OPTR.pop ();}if(exp[i]!='#'){OPTR.push (exp[i]);i++;}break;}}//end switch}//end else}//end whileT = PTR.top();PTR.pop ();}void PostOrderTraverse(BiTree &T, char * exp ,int &count){//后序遍历表达式树T,获取树中每个结点的数据值生成逆波兰表达式exp //T是表达式树的根节点;字符串exp保存逆波兰表达式;count保存exp中字符的个数//后序遍历中,处理根结点时,依据T->len的值,把T->data中的字符依次添加到当前exp字符串的尾端//添加完T->data后,再添加一个空格字符,同时更新count计数器的值。
算术表达式求值数据结构实验报告
算法的正确性和效率分析
正确性
所有实现的数据结构都正确地实现了算术表达式求值的功能,没有出现计算错 误的情况。
效率
在处理大量数据时,使用堆栈(Stack)和队列(Queue)的数据结构表现最 佳。堆栈在处理后缀表达式时效率最高,而队列在处理中缀表达式时效率最高 。
数据结构优化的效果评估
使用哈希表(Hash Table)
展望未来,希望能够进一步研究算术 表达式求值算法的优化和改进,提高 计算效率和精度。
THANKS
感谢观看
05
列表(List)
数组(Array) 元组(Tuple) 集合(Set)
字典( Dictiona…
由于列表在Python中是动 态数组,其性能在处理大 量数据时相对较差。在算 术表达式求值中,列表的 平均执行时间最长。
使用NumPy库的数组结构 ,其性能在处理大量数据 时优于列表。但在算术表 达式求值中,其性能仍然 不如其他数据结构。
03
了解如何使用栈数据结构实现括号匹配和回退机制 。
掌握数据结构在算术表达式求值中的应用
01 熟悉使用数组、链表等基本数据结构存储和操作 算术表达式。
02 掌握如何使用树形数据结构表示算术表达式,如 二叉树或表达式树。
03 了解动态规划在优化算术表达式求值中的运用。
提高编程能力和解决问题的能力
01
在处理重复元素时,使用哈希表可以显著提高数据结构的效率。在算术表达式求值中,哈希表的使用可以减少重 复计算和查找的时间。
预处理输入数据
对输入的算术表达式进行预处理,如括号消除、指数化等,也可以提高数据结构的效率。预处理可以减少运算的 复杂度和时间。
05
实验总结
本次实验的收获和体会
表达式求值 实验报告
表达式求值实验报告表达式求值实验报告一、引言表达式求值是计算机科学中一个重要的概念,它涉及到对数学表达式的计算和求解。
在本次实验中,我们将探讨表达式求值的相关算法和实现方法,并通过编程实现一个简单的表达式求值器。
二、算法原理1. 表达式的表示方法在计算机中,我们通常使用字符串来表示表达式。
例如,一个简单的数学表达式"2 + 3 * 4"可以表示为字符串"2+3*4"。
在实现表达式求值的算法时,我们需要将字符串中的数字和运算符进行分离,以便进行后续的计算。
2. 中缀表达式转后缀表达式为了方便计算,我们通常将中缀表达式转换为后缀表达式。
后缀表达式也称为逆波兰表达式,它的特点是运算符位于操作数的后面。
例如,上述的中缀表达式"2+3*4"可以转换为后缀表达式"234*+"。
转换的方法可以通过使用栈来实现。
3. 后缀表达式求值得到后缀表达式后,我们可以通过扫描表达式并使用栈来求解。
当遇到操作数时,将其压入栈中;当遇到运算符时,从栈中弹出相应数量的操作数进行计算,并将结果压入栈中。
最终,栈中的唯一元素即为表达式的求值结果。
三、实验过程1. 数据结构设计为了实现表达式求值器,我们需要设计相应的数据结构。
在本次实验中,我们选择使用栈来存储操作数和运算符。
2. 中缀表达式转后缀表达式首先,我们需要编写一个函数来将中缀表达式转换为后缀表达式。
该函数的实现可以通过使用栈和遍历字符串来实现。
具体的步骤如下:- 创建一个空栈和一个空字符串用于存储后缀表达式。
- 从左到右遍历中缀表达式的每个字符。
- 如果遇到操作数,直接将其添加到后缀表达式字符串中。
- 如果遇到运算符,将其与栈顶的运算符进行比较:- 如果栈为空或栈顶为左括号"(",则直接将运算符入栈。
- 如果栈顶的运算符优先级低于当前运算符,则将当前运算符入栈。
- 如果栈顶的运算符优先级高于或等于当前运算符,则将栈顶的运算符弹出并添加到后缀表达式字符串中,直到栈顶的运算符优先级低于当前运算符或栈为空。
数据结构表达式求值实验报告
数据结构表达式求值实验报告一、实验目的本次实验的主要目的是通过实现表达式求值的程序,深入理解数据结构和算法在解决实际问题中的应用。
具体包括掌握栈这种数据结构的操作和使用,熟悉表达式的转换和计算过程,提高编程能力和问题解决能力。
二、实验环境本次实验使用的编程语言为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”等,程序能够正确地将其转换为后缀表达式,并计算出结果。
数据结构表达式求值实验报告
竭诚为您提供优质文档/双击可除数据结构表达式求值实验报告篇一:数据结构实验二——算术表达式求值实验报告《数据结构与数据库》实验报告实验题目算术表达式求值学院:化学与材料科学学院专业班级: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、实验目的:____________________________2、实验环境:____________________________3、实验原理:____________________________4、实验步骤:____________________________5、测试用例及结果:____________________________6、实验总结:____________________________11 实验目的本实验的主要目的是通过使用数据结构和算法来实现表达式求值的功能,加深对栈、队列等数据结构的理解和运用,提高编程能力和解决实际问题的能力。
111 具体目标包括掌握中缀表达式转换为后缀表达式的方法。
利用栈结构实现后缀表达式的求值运算。
能够处理表达式中的运算符优先级和括号。
12 实验环境本次实验使用的编程环境为具体编程语言和版本,在操作系统名称操作系统上进行。
121 所需软件和工具编程软件名称:用于编写和调试代码。
测试工具名称:用于对程序进行测试和验证。
13 实验原理表达式求值是程序设计中的一个常见问题。
中缀表达式符合人们的日常书写习惯,但直接求值较为复杂。
将中缀表达式转换为后缀表达式后,求值过程会变得更加简单和直观。
131 中缀转后缀表达式的原理遇到操作数,直接输出。
遇到运算符,将其与栈顶运算符进行优先级比较。
若优先级高于栈顶运算符,则入栈;否则,弹出栈顶运算符并输出,直到当前运算符优先级高于栈顶运算符或栈为空,然后将当前运算符入栈。
遇到左括号,直接入栈。
遇到右括号,弹出栈顶运算符并输出,直到遇到左括号,左括号出栈但不输出。
132 后缀表达式求值的原理从左到右扫描后缀表达式。
遇到操作数,压入栈中。
遇到运算符,从栈中弹出两个操作数,进行相应运算,将结果压入栈中。
扫描结束后,栈顶元素即为表达式的结果。
14 实验步骤141 数据结构设计定义一个栈来存储运算符。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验课程名称专业班级学生姓名学号指导教师20 至 20 学年第学期第至周算术表达式求值演示一、概述数据结构课程设计,要求学生在数据结构的逻辑特性和物理表示、数据结构的选择和应用、算法的设计及其实现等方面,加深对课程基本容的理解。
同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。
在这次的课程设计中我选择的题目是算术表达式求值演示。
表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的一个典型例子。
设计一个程序,演示用算符优先法对算术表达式求值的过程。
深入了解栈和队列的特性,以便在解决实际问题中灵活运用它们,同时加深对这种结构的理解和认识。
二、系统分析1.以字符列的形式从终端输入语确的、不含变量的整数表达式。
利用已知的算符优先关系,实现对算术四则混合运算表达式的求值,并仿照教科书的例子在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。
2.一般来说,计算机解决一个具体问题时,需要经过几个步骤:首先要从具体问题抽象出一个适当的数学模型,然后设计一个解决此数学模型的算法,最后编出程序,进行测试,调试直至得到想要的答案。
对于算术表达式这个程序,主要利用栈,把运算的先后步骤进行分析并实现简单的运算!为实现算符优先算法,可以使用两个栈,一个用以寄存运算符,另一个用以寄存操作数和运算结果。
3.演示程序是以用户于计算机的对话方式执行,这需要一个模块来完成使用者与计算机语言的转化。
4.程序执行时的命令:本程序为了使用具体,采用菜单式的方式来完成程序的演示,几乎不用输入什么特殊的命令,只需按提示输入表达式即可。
(要注意输入时格式,否者可能会引起一些错误)5. 测试数据。
三、概要设计一个算术表达式中除了括号、界限符外,还包括运算数据和运算符。
由于运算符有优先级别之差,所以一个表达式的运算不可能总是从左至右的循序执行。
每次操作的数据或运算符都是最近输入的,这与栈的特性相吻合,故本课程设计借助栈来实现按运算符的优先级完成表达式的求值计算。
算法设计程序包含三个模块(1) 主程序模块,其中主函数为void main{输入表达式;根据要求进行转换并求值;输出结果;}(2) 表达式求值模块——实现具体求值。
(3) 表达式转换模块——实现转换。
各个函数之间的调用关系栈的抽象数据类型定义ADT SqStack{数据对象:D={a i| a i∈ElemSet,i=1,2,3……,n,n≥0}数据关系:R1={<a i-1,a i>| a i-1,a i∈D,i=1,2,3,……,n}约定其中a i端为栈底,a n端为栈顶。
操作集合:(1)void InitStack1(SqStack1 &S1);//声明栈建立函数(2)void InitStack2(SqStack2 &S2);//声明栈建立函数(3)void evaluate(SqStack1 &S1,SqStack2 &S2);//确定如何入栈函数(4)void Push1(SqStack1 &S1,char e);//声明入栈函数(5)void Push2(SqStack2 &S2,float e);//声明入压栈函数(6)char GetTop1(SqStack1 &S1);//声明取栈顶元素函数(7)float GetTop2(SqStack2 &S2);//声明取栈顶元素函数(8)char Pop1(SqStack1 &S1);//声明出栈函数(9)float Pop2(SqStack2 &S2);//声明出栈函数(10)char Compare(char m,char n);//声明比较函数(11)float Operate(float a,char rheta,float b);//声明运算函数(12)void DispStack1(SqStack1 &S1);//从栈底到栈顶依次输出各元素(13)void DispStack2(SqStack2 &S2);//从栈底到栈顶依次输出各元素}ADT SqStack结构分析:栈中的数据节点是通过数组来存储的。
因为在C语言中数组是用下标从零开始的,因此我们在调用他们的数据是要特别注意。
指针变量的值要么为空(NULL),不指向任何结点;要么其值为非空,即它的值是一个结点的存储地址。
注意,当P为空值时,则它不指向任何结点,此时不能通过P来访问结点,否则会引起程序错误。
如果输入的数字不符合题目要求,则会产生错误结果。
算法的时空分析:时间和空间性能分析:时间上,对于含n个字符的表达式,无论是对其进行合法性检测还是对其进行入栈出栈操作n次,因此其时间复杂度为O(n)。
空间上,由于是用数组来存储输入的表达式,用栈来存储运算中的数据和运算符,而栈的本质也用到的数组,数组在定义时必须确定其大小。
在不知表达式长度的情况下确定数组的长度确非易事,此时极易造成空间的浪费,因此空间性能不是很好。
四、详细设计源程序#include<iostream>using namespace std;#define STACK_INIT_SIZE 100#define STACKINCREMENT 10typedef struct //运算符栈{char *base;char *top;int stacksize;}SqStack1;typedef struct //运算数栈{float *base;float *top;int stacksize;}SqStack2;void InitStack1(SqStack1 &S1);//声明栈建立函数void InitStack2(SqStack2 &S2);//声明栈建立函数void evaluate(SqStack1 &S1,SqStack2 &S2);//确定如何入栈函数void Push1(SqStack1 &S1,char e);//声明入栈函数void Push2(SqStack2 &S2,float e);//声明入压栈函数char GetTop1(SqStack1 &S1);//声明取栈顶元素函数float GetTop2(SqStack2 &S2);//声明取栈顶元素函数char Pop1(SqStack1 &S1);//声明出栈函数float Pop2(SqStack2 &S2);//声明出栈函数char Compare(char m,char n);//声明比较函数float Operate(float a,char rheta,float b);//声明运算函数void DispStack1(SqStack1 &S1);//从栈底到栈顶依次输出各元素void DispStack2(SqStack2 &S2);//从栈底到栈顶依次输出各元素/*主函数*/void main(){SqStack1 S1;//定义运算符栈SqStack2 S2;//定义运算数栈//freopen("data1.in","r",stdin);//freopen("data1.out","w",stdout);InitStack1(S1);//调用栈建立函数InitStack2(S2);//调用栈建立函数evaluate(S1,S2);//调用确定如何入栈函数cout<<"按任意键结束!"<<endl;}/*运算符栈函数*/void InitStack1(SqStack1 &S1)//构造一个空栈S1{S1.base=(char *)malloc(STACK_INIT_SIZE *sizeof(char));if(!S1.base)cout<<"存储分配失败!";//存储分配失败S1.top=S1.base;S1.stacksize=STACK_INIT_SIZE;}void Push1(SqStack1 &S1,char e)//入栈{if(S1.top-S1.base>=S1.stacksize)//如果栈满,追加存储空间{S1.base=(char *)realloc(S1.base,(S1.stacksize+STACKINCREMENT)*sizeof(char));if(!S1.base) cout<<"存储分配失败!";else{S1.top=S1.base+S1.stacksize;S1.stacksize=S1.stacksize+STACKINCREMENT;}}*S1.top=e;S1.top=S1.top+1;//将元素压入栈中,指针上移}char GetTop1(SqStack1 &S1)//取栈顶元素{char e;if(S1.top==S1.base)cout<<"\n\t\t\t运算符栈已空!\n";else e=*(S1.top-1);return e;}void DispStack1(SqStack1 &S1)//从栈底到栈顶依次输出各元素{char e,*p;if(S1.top==S1.base)cout<<" ";else{p=S1.base;while(p<S1.top){e=*p;p++;cout<<e;}}}char Pop1(SqStack1 &S1)//出栈{char e;if(S1.top==S1.base)cout<<"\n\t\t\t运算符栈已空!\n";e=*(--S1.top);return e;}/*运算数栈函数*/void InitStack2(SqStack2 &S2)//构造一个空栈S2{S2.base=(float *)malloc(STACK_INIT_SIZE *sizeof(float));if(!S2.base)cout<<"存储分配失败!";//存储分配失败S2.top=S2.base;S2.stacksize=STACK_INIT_SIZE;}void Push2(SqStack2 &S2,float e)//入栈{if(S2.top-S2.base>=S2.stacksize)//栈满,追加存储空间{S2.base=(float *)realloc(S2.base,(S2.stacksize+STACKINCREMENT)*sizeof(float));if(!S2.base)cout<<"存储分配失败!";else{S2.top=S2.base+S2.stacksize;S2.stacksize=S2.stacksize+STACKINCREMENT;}}*S2.top=e;S2.top=S2.top+1;//将元素e入栈,指针上移}void DispStack2(SqStack2 &S2)//从栈底到栈顶依次输出各元素{float e,*p;if(S2.top==S2.base)cout<<" ";else{p=S2.base;while(p<S2.top){e=*p;p++;cout<<e;}}}float GetTop2(SqStack2 &S2)//取栈顶元素{float e;if(S2.top==S2.base) cout<<"\n\t\t运算数栈已空!";else e=*(S2.top-1);return e;}float Pop2(SqStack2 &S2)//出栈{float e;if(S2.top==S2.base)cout<<"\n\t\t运算数栈已空!";e=*(--S2.top);return e;}/*确定如何入栈函数*/void evaluate(SqStack1 &S1,SqStack2 &S2){char c;float t,e;int n=0,i=1,j=0,k=0,l=0;char ch[STACK_INIT_SIZE];int s=1;int flag=0,flag2=0;float p1,p2;char ch1;Push1(S1,'#');//将'#'入栈,作为低级运算符cout<<"●请输入不含变量的表达式(以#结束!):\n ";cin>>ch;c=ch[0];cout<<"\n●对表达式求值的操作过程如下:"<<"\n______________________________________________________________________________ __\n"<<"步骤\t运算符栈S1\t运算数栈S2\t输入字符\t\t主要操作";while(c!='#'||GetTop1(S1)!='#'){cout<<"\n__________________________________________________________________________ ______\n";cout<<i++<<"\t";DispStack1(S1);cout<<"\t\t";DispStack2(S2);cout<<"\t\t";if(flag==1){k--;flag=0;}if(flag2){k+=flag2;flag2=0;}for(l=0;l<k;l++)cout<<' ';for(j=k;ch[j]!='\0';j++)cout<<ch[j];if(ch[k]!='#'&&flag!=1) {k++;flag=0;}as:if(!(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')){//输入的字符如果不是运算符号,则继续输入直到输入的是运算符为止,将非运算符转换成浮点数if(!(c=='.')&&n>=0){e=float(c-48);n++;if(n==1)t=e;else if(n>1)t=t*10+e;c=ch[s++];}if(n==-1){e=float(c-48);t=t+e/10;c=ch[s++];}if(c=='.'){n=-1;c=ch[s++];}if((c>='0'&&c<='9')||c=='.'){flag2++;goto as;}if(c<'0'||c>'9'){Push2(S2,t);}cout<<"\t\tPush2(S2,"<<t<<")";}else//输入的是运算符{n=0;//非运算型数据计数器清零switch(Compare(GetTop1(S1),c))//比较运算符的优先级{case '<'://栈顶元素优先级低,则入栈且继续输入Push1(S1,c);cout<<"\t\tPush1(S1,"<<c<<")";c=ch[s++];break;case '='://栈顶元素优先级相等,脱括号并接收下一字符Pop1(S1);cout<<"\t\tPop1(S1)";c=ch[s++];break;case '>'://栈顶元素优先级高,则退栈并将运算结果入栈p1=Pop2(S2);p2=Pop2(S2);ch1=Pop1(S1);Push2(S2,Operate(p2,ch1,p1));cout<<"\t\tOperate("<<p2<<','<<ch1<<','<<p1<<')';flag=1;break;}}}cout<<"\n__________________________________________________________________________ ______\n";cout<<i<<'\t'<<'#'<<"\t\t"<<GetTop2(S2)<<"\t\t";for(j=0;j<k;j++) cout<<' ';cout<<"#"<<"\t\t"<<"RETURN(GETTOP(S2))";cout<<"\n__________________________________________________________________________ ______\n";if(S2.top-1==S2.base)//显示表达式最终结果cout<<"\n●表达式的结果为:"<<GetTop2(S2)<<endl;else cout<<"\n表达式出错!\n";}char Compare(char m,char n)//运算符的优先级比较{if(n=='+'||n=='-')//输入符号为"+"、"-"{if(m=='('||m=='#')return '<';//栈顶元素为"("、"#",此时栈顶符号优先级低,返回"<"else return '>';//否则,栈顶符号优先级高,返回">"}else if(n=='*'||n=='/')//输入的符号为"*"、"/"{if(m==')'||m=='*'||m=='/')return '>';//栈顶元素为")"、"*"、"/",此时栈顶符号优先级高,返回">"else return '<';//否则,栈顶符号优先级低,返回"<"}else if(n=='(')return'<';//输入的符号为"(",则直接返回"<"else if(n==')')//输入的符号为")"{if(m=='(')return'=';//栈顶元素为"(",此时优先级同,返回"="else return '>';//否则,栈顶符号优先级高,返回">"}else //输入符号为其他{if(m=='#')return'=';//栈顶元素为"#",此时优先级同,返回"="else return '>';//否则,栈顶符号优先级高,返回">"}}float Operate(float a,char theta,float b)//运算函数{float tmp=0;if (theta=='+')tmp=a+b;//从运算符栈取出的符号为"+",则运算数栈的两元素相加,并返回else if(theta=='-')tmp=a-b;//从运算符栈取出的符号为"-",则运算数栈的两元素相减,并返回else if(theta=='*')tmp=a*b;//从运算符栈取出的符号为"*",则运算数栈的两元素相乘,并返回else if(theta=='/') //从运算符栈取出的符号为"/",则运算数栈的两元素相除,并返回{if(b==0) cout<<"\n表达式出错!除数不能为0!\n";else tmp=a/b;}return tmp;}五、运行与测试第六章总结与心得数据结构的研究不仅涉及到计算机硬件的研究,而且和计算机软件的研究有着更密切的关系,无论是编译程序还是操作系统,都涉及到数据元素在存储器中的分配问题。