《数据结构课程设计》表达式求值实验报告
(完整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 栈的栈顶元素和当前读入的字符均为"#")。
数据结构实验报告--表达式求值

void Initstack1(stack1 *s>
{
(*s>->base = (int *>malloc(SIZE * (sizeof(int>>>
。
(*s>->top = (*s>->base
。
(*s>->stacksize = INCREMENT 。
}
int Ifempty2(stack2 *s>
<6)中缀转后缀并计算模块:
( 三 > 详细设计
1.元素类型 , 结点类型和指针类型:
typedef struct{
int stacksize 。 int *base 。
int *top 。
}Sqstack1,*stack1 。
typedef struct{
int stacksize 。
char *base 。
{
if(((a=='*'>||(a=='/'>>&&((b=='+'>||(b=='-'>||(b=='#'>>>
5PCzVD7HxA
return '>'
。
else
return '<'
。
}
<4)运算符操作模块;
int Operate(int a,char b,int c>
{
int t 。
if(b == '+'> t = a + c
{
数据结构表达式求值实验报告

实验报告课程名:数据结构(C语言版)实验名:表达式求值姓名:班级:学号:时间:2014.10.25一实验目的与要求1. 了解栈的应用2. 利用栈进行算术表达式求值二实验内容1.以字符串的形式给出一个算术表达式, 计算出该算术表达式的值。
2.表达式中可能出现”+”, ”−”, ”∗”, ”/”, ”(”, ”)”。
三实验结果与分析分析:r:读入字符t:栈顶字符r( ) # 低优先运算符高优先运算符( 入栈出栈错误入栈入栈) 错误错误错误错误错误t # 入栈错误结束入栈入栈低优先运算符入栈出栈+运算出栈+计算出栈+计算入栈高优先运算符入栈出栈+运算出栈+计算出栈+计算出栈+计算1, 入栈2, 错误3, 出栈4, 出栈+计算5, 结束( ) # 低优先运算符高优先运算符( 1 3 2 1 1) 2 2 2 2 2# 1 2 5 1 1低优先运算符 1 4 4 4 1高优先运算符 1 4 4 4 4此实验可用两个栈和数组来实现,一个操作栈,一个数字栈,两个栈的字符进行优先权比较可得到5种结果。
首先置操作栈为空栈,表达式起始符“#”作为数字栈的栈底元素,依次读入表达式的每个字符,若是操作字符进操作栈,若是数字进数字栈,操作栈和数字栈的栈顶元素比较优先权后进行相应操作,直至结束,最后输出值即可。
实验程序:#include<stdio.h>#include<stdlib.h>#include<string.h>int change(char c)//字符转换{int j=-1;switch(c){case '(':j=0;break;case ')':j=1;break;case '#':j=2;break;case '+':j=3;break;case '-':j=3;break;case '*':j=4;break;case '/':j=4;break;}return(j);}int compu(int x,int y,char c)//数字计算转换{int j=-1;switch(c){case '+':j=x+y;break;case '-':j=x-y;break;case '*':j=x*y;break;case '/':j=x/y;break;}return(j);}void get(char a[],int num_op,int method[5][5]){int a_length=strlen(a)+1;//表达式的长度int p=0,num_p=0,op_p=0;int *num_s=(int *)malloc((a_length)*sizeof(int));// char *op_s=(char *)malloc((a_length)*sizeof(int));// op_s[op_p]='#';op_p++;//进字符栈int k=-1;//输出结果判断int ox,oy;while(1){char c=a[p];//将表达式中的字符一个一个赋值给cif(c>='0'&&c<='9')//判断是不是数字{num_s[num_p]=c-48;//将Ascll码转换成对应数字num_p++;//进数字栈p++;//代表表达式的位置开始为0指向第一位}else{int t=method[change(op_s[op_p-1])][change(c)];//将5种操作的一种传给tswitch(t){case 1:op_s[op_p]=c;op_p++;p++;break;case 2:k=0;break;case 3:op_p--;p++;break;case 4:ox=num_s[num_p-2];oy=num_s[num_p-1];num_p=num_p-2;num_s[num_p]=compu(ox,oy,op_s[op_p-1]);//将计算的值存入num_s[]num_p++;//入数字栈op_p--;break;case 5:k=1;break;}}if(k>=0)//跳出循环{break;}}switch(k)//0错误,1输出结果{case 0:printf("表达式错误!");break;case 1:printf("%s=%d\n",a,num_s[num_p-1]);break;}}int main(int argc,char *argv[]){ char a[20];puts("请输入个位数的表达式:");gets(a);int num_op=5;//表示操作的种数int method[5][5]={{1,3,2,1,1},{2,2,2,2,2},{1,2,5,1,1},{1,4,4,4,1},{1,4,4,4,4}};//1表示入栈,2表示错误,//3表示出栈,4表示出栈+计算,//5表示结束get(a,num_op,method);return 0;}图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)。
数据结构实验报告 表达式求值

(一) 需求分析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、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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<<" ";elsep=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;}五、运行与测试第六章总结与心得数据结构的研究不仅涉及到计算机硬件的研究.而且和计算机软件的研究有着更密切的关系.无论是编译程序还是操作系统.都涉及到数据元素在存储器中的分配问题。