数据结构实验二——算术表达式求值实验报告

合集下载

数据结构表达式求值实验报告

数据结构表达式求值实验报告

竭诚为您提供优质文档/双击可除数据结构表达式求值实验报告篇一:数据结构实验二——算术表达式求值实验报告《数据结构与数据库》实验报告实验题目算术表达式求值学院:化学与材料科学学院专业班级: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!二、概要设计拟采用两种类型的展分别对操作数和操作符进行操作。

数据结构实验报告--表达式求值

数据结构实验报告--表达式求值

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
{

算术表达式求值实验报告

算术表达式求值实验报告

算术表达式求值实验报告前言算术表达式求值是计算机科学中比较基础的内容,同时也是很实用的技能,因为有时候我们需要用程序来计算一些复杂的数学运算。

在本次实验中,我们将对算术表达式的求值进行深入研究,并实际编写程序来实现这一功能。

实验原理算术表达式通常由数字、运算符和括号组成,我们需要将其转换为计算机能够直接执行的形式。

常见的算术表达式求值方法有两种:1.中缀表达式求值中缀表达式就是我们平时所熟悉的数学表达式,如2+3*4-5/2。

中缀表达式求值需要遵循一定的运算符优先级和括号的影响,可以通过栈来实现。

首先,我们需要将中缀表达式转换为后缀表达式,即将运算符放在数字后面。

具体的转换方法可以使用栈来实现。

遍历中缀表达式,遇到数字就直接输出,遇到运算符就将其与栈顶运算符进行比较,如果优先级高于栈顶运算符,则将其入栈,否则将栈顶运算符弹出并输出,直到遇到优先级小于等于栈顶运算符或者栈顶为空时,将运算符入栈。

最后将栈中的运算符依次弹出并输出即可。

转换为后缀表达式之后,我们可以通过再次遍历后缀表达式来求值。

遇到数字将其入栈,遇到运算符则弹出栈顶两个数字进行运算,并将结果入栈。

遍历完毕后,栈中剩下的数字就是最终结果。

2.前缀表达式求值前缀表达式就是将运算符放在数字前面的表达式,如:- + * 3 4 5 6。

前缀表达式求值与后缀表达式求值类似,不同之处在于需要从右至左遍历表达式,并将运算符与栈顶数字进行操作。

实验步骤在本次实验中,我们将通过 Python 语言来实现算术表达式求值功能。

具体步骤如下:1. 输入待求值的算术表达式。

2. 对算术表达式进行转换,得到后缀表达式或前缀表达式。

3. 遍历后缀表达式或前缀表达式,求出最终结果。

4. 输出结果。

实验结果我们在 Python 中编写了求解算术表达式的程序,以下是一些样例输入和输出:1. 输入:2+3*4 输出:142. 输入:(2+3)*4 输出:203. 输入:-+*3456 输出:-9通过多组测试,我们可以发现程序能够正确地求解各种算术表达式,包括包含括号和负数的表达式。

数据结构实验二——算术表达式求值实验报告

数据结构实验二——算术表达式求值实验报告

《数据结构与数据库》实验报告实验题目算术表达式求值学院:化学与材料科学学院专业班级:09级材料科学与工程系PB0920603姓名:李维谷学ﻩﻩ号:PB09206285邮ﻩ箱:指导教师:贾伯琪实验时间:2010年10月10日一、需要分析问题描述:表达式计算就是实现程序设计语言得基本问题之一,它得实现就是栈得应用得一个典型例子.设计一个程序,演示通过将数学表达式字符串转化为后缀表达式,并通过后缀表达式结合栈得应用实现对算术表达式进行四则混合运算。

问题分析:在计算机中,算术表达式由常量、变量、运算符与括号组成.由于不同得运算符具有不同得优先级,又要考虑括号,因此,算术表达式得求值不可能严格地从左到右进行。

因而在程序设计时,借助栈实现.设置运算符栈(字符型)与运算数栈(浮点型)辅助分析算符优先关系。

在读入表达式得字符序列得同时完成运算符与运算数得识别处理,然后进行运算数得数值转换在进行四则运算.在运算之后输出正确运算结果,输入表达式后演示在求值中运算数栈内得栈顶数据变化过程,最后得到运算结果。

算法规定:输入形式:一个算术表达式,由常量、变量、运算符与括号组成(以字符串形式输入)。

为使实验更完善,允许操作数为实数,操作符为(、)、、(表示小数点)、+、-、*、/、^(表示乘方),用#表示结束。

输出形式:演示表达式运算得中间结果与整个表达式得最终结果,以浮点型输出。

程序功能:对实数内得加减乘除乘方运算能正确得运算出结果,并能正确对错误输入与无定义得运算报错,能连续测试多组数据。

测试数据:正确输入:12*(3、6/3+4^2—1)#输出结果:194、4无定义运算:12*(3、6/(2^2—4)+1)#输出结果:表达式出错,除数为0,无意义错误输入:12+s#输出结果:ERROR!二、概要设计拟采用两种类型得展分别对操作数与操作符进行操作.程序中将涉及下列两个抽象数据类型:1、设定“操作数”得栈得抽象数据类型定义:ADT SqStack_f{ﻩ数据对象:D={ﻩ数据关系:R1={〈>|,,i=2,…,n}约定端为栈顶,端为栈底。

数据结构表达式求值实验报告

数据结构表达式求值实验报告

实验报告课程名:数据结构(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.表达式求值运行结果。

数据结构表达式求值(中缀)实验报告

数据结构表达式求值(中缀)实验报告

数据结构表达式求值(中缀)实验报告题目名称表达式求值学号姓名指导教师日期一1. 问题描述:在计算机中,算术表达式由常量、变量、运算符和括号组成。

由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行,在程序设计时,借助栈实现。

2. 表达式求值这个程序,主要利用栈和数组,把运算的先后步骤进行分析并实现简单的运算,以字符列的形式从终端输入语法的正确的、不含变量的整数表达式。

利用已知的算符优先关系,实现对算术四则运算的求值,在求值中运用栈、运算栈、输入字符和主要操作的变化过程。

该程序相当于一个简单的计算机计算程序,只进行简单的加减乘除和带括号的四则运算。

1、基本思想(中缀表达式求值)要把一个表达式翻译成正确求值的一个机器指令序列,或者直接对表达式求值,首先要能够正确解释表达式,要了解算术四则运算的规则即:(1)先乘除后加减;(2)从左到右计算;(3)先括号内,后括号外。

下表定义的运算符之间的关系:b + - * / () # a+ > > < < < > > _ > > < < < > > * > > > > < > > / > > > > < > > ( < < < < < = ) > > > > > > # < < < < < =为了实现运算符有限算法,在程序中使用了两个工作栈。

分别是:运算符栈OPTR,操作数栈OPND.基本思想:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;(2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈得栈顶运算符比较优先级后作相应操作。

数据结构实验报告-算术表达式求值

数据结构实验报告-算术表达式求值

- - 1.前言12.概要设计12.1 数据构造设计12.2 算法设计12.3 ADT描述22.4 功能模块分析23.详细设计33.1 数据存储构造设计33.2主要算法流程图〔或算法伪代码〕44.软件测试75.心得体会8参考文献8附录9- -优质-..1.前言在计算机中,算术表达式由常量、变量、运算符和括号组成。

由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进展。

因而在程序设计时,借助栈实现。

算法输入:一个算术表达式,由常量、变量、运算符和括号组成〔以字符串形式输入〕。

为简化,规定操作数只能为正整数,操作符为+、-*、/,用#表示完毕。

算法输出:表达式运算结果。

算法要点:设置运算符栈和运算数栈辅助分析算符优先关系。

在读入表达式的字符序列的同时,完成运算符和运算数的识别处理,以及相应运算。

2.概要设计2.1 数据构造设计任何一个表达式都是由操作符,运算符和界限符组成的。

我们分别用顺序栈来存放表达式的操作数和运算符。

栈是限定于紧仅在表尾进展插入或删除操作的线性表。

顺序栈的存储构造是利用一组连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置,base为栈底指针,在顺序栈中,它始终指向栈底,即top=base可作为栈空的标记,每当插入新的栈顶元素时,指针top增1,删除栈顶元素时,指针top减1。

2.2 算法设计为了实现算符优先算法。

可以使用两个工作栈。

一个称为OPTR,用以存放运算符,另一个称做OPND,用以存放操作数或运算结果。

1.首先置操作数栈为空栈,表达式起始符〞#〞为运算符栈的栈底元素;2.依次读入表达式,假设是操作符即进OPND栈,假设是运算符那么和OPTR栈的栈顶运算符比拟优先权后作相应的操作,直至整个表达式求值完毕〔即OPTR栈的栈顶元素和当前读入的字符均为〞. .word.zl.数据构造课程设计第 2 页#〞〕。

数据结构表达式求值完整篇(含实验报告)

数据结构表达式求值完整篇(含实验报告)
voidOPND_Pop(Sqstack_OPND
&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);
//操作数栈初始化

数据结构与算法课程实验二:算术表达式求值

数据结构与算法课程实验二:算术表达式求值

• 一种方便地求算符优先函数的方法——迭代法
若已知运算符之间的优先关系,可按如下步骤构造 优先函数:
1、对每个运算符a(包括#在内)令f(a)=g(a)=1 2、如果a⋗b且f(a)<=g(b)令f(a)=g(b)+1 3、如果a⋖b且f(a)>=g(b)令g(b)= f(a)+1 4、如果a≐b而f(a) ≠g(b),令
选做内容 1
• 变算符优先矩阵为算符优先函数:
• 在实际实现算符优先分析算法时,一般不 用优先矩阵,而是用两个函数:入栈优先 函数f和比较优先函数g。它们如下定义:
若 θ1⋖θ2 若 θ1≐θ2 若 θ1⋗θ2
则 f(θ1) < g(θ2) 则 f(θ1) = g(θ2) 则 f(θ1) > g(θ2)
实现提示
• (1)设置运算符栈和运算数栈辅助分析算 符优先关系。
• (2)在读入表达式的字符序列的同时,完 成运算符和运算数(整数)的识别处理, 以及相应的运算。
• (3)在识别出运算数的同时,要将其字符 序列形式转换成整数形式。
• (4)在程序的适当位置输出运算符栈、运 算数栈、输入字符和主要操作的内容。
实验二
算术表达式求值
问题描述
• 表达式计算是实现程序设 计语言的基本问题之一, 也是栈的应用的典型例子。 设计一个程序,演示用算 符优先法对算术表达式求 值的过程。
基本要求
• 以字符序列的形式从键盘输入语 法正确的,不含变量的整型表达式。 利用教科书表3.1给出的算符优先关系, 实现对算术四则混合运算表达式的求 值,并仿照教科书的例3.1演示在求值 中运算符栈、运算数栈、输入字符和 主要操作的变化过程。
算符优先关系矩阵
+-*/

数据结构表达式求值实验报告

数据结构表达式求值实验报告

数据结构表达式求值实验报告数据结构表达式求值实验报告⒈引言本实验旨在研究和实现数据结构中表达式求值的算法。

表达式求值是计算机科学中常见的问题,对于计算机程序的正确性和性能具有重要影响。

本报告将详细介绍实验设计、实验步骤、实验结果及分析,并对实验过程中遇到的问题进行讨论。

⒉实验设计⑴实验目的本实验的目的是实现一个可以对常见的算术表达式进行求值的算法,包括支持基本的加减乘除运算符和括号。

⑵实验环境●操作系统:Windows 10●开发语言:C++●开发工具:Visual Studio 2019⑶数据结构设计为了实现表达式求值的算法,我们需要设计适当的数据结构来存储和处理表达式。

本实验中,我们选择使用栈来实现表达式求值。

●表达式栈:用于存储操作数和运算符。

●运算符栈:用于存储运算符。

⑷算法设计表达式求值的算法可以分为以下几个步骤:●遍历表达式,逐个处理操作数和运算符:●如果是操作数,入表达式栈。

●如果是运算符,与运算符栈栈顶元素进行比较,根据优先级决定如何处理。

●当表达式遍历完成后,依次处理剩余的运算符。

●最终表达式栈中的元素即为求值结果。

⒊实验步骤⑴数据结构实现根据设计,我们首先实现表达式栈和运算符栈的数据结构,包括入栈、出栈等操作。

⑵表达式输入与预处理用户输入待求值的表达式,进行预处理,去除空格、验证表达式的合法性等。

⑶表达式求值算法实现根据前述的算法设计,实现表达式求值的算法,利用表达式栈和运算符栈来处理表达式。

⑷测试与结果分析对于不同的测试用例,进行表达式求值的测试,并分析结果的正确性和性能。

⒋实验结果与分析经过实验测试,我们得到了表达式求值的结果。

结果显示,我们的算法能够正确地求得表达式的值,而且性能良好。

⒌讨论与总结在实验过程中,我们遇到了一些问题,并进行了讨论和解决。

通过这个实验,我们更加深入地理解了表达式求值的算法,并对数据结构的应用有了更清晰的认识。

附件:无法律名词及注释:●无。

数据结构实验二——算术表达式求值实验报告

数据结构实验二——算术表达式求值实验报告

数据结构实验二——算术表达式求值实验报告算术表达式求值实验报告一、引言算术表达式求值是计算机科学中一个重要的基础问题,它涉及到了数据结构和算法的应用。

本实验旨在通过实现一个算术表达式求值的程序,加深对数据结构中栈的理解和应用,并掌握算术表达式的求值过程。

二、实验目的1. 理解算术表达式的基本概念和求值过程;2. 掌握栈的基本操作和应用;3. 实现一个能够正确求解算术表达式的程序;4. 进一步熟悉编程语言的使用。

三、实验内容1. 设计并实现一个栈的数据结构;2. 实现算术表达式求值的算法;3. 编写测试用例,验证程序的正确性;4. 进行性能测试,分析算法的时间复杂度。

四、实验方法与步骤1. 设计栈的数据结构在本实验中,我们选择使用数组来实现栈的数据结构。

栈的基本操作包括入栈(push)、出栈(pop)、判断栈空(isEmpty)和获取栈顶元素(top)等。

2. 算术表达式求值算法算术表达式求值的一种常用算法是通过后缀表达式进行求值。

具体步骤如下: - 将中缀表达式转换为后缀表达式;- 通过栈来求解后缀表达式;- 返回最终的计算结果。

3. 编写测试用例编写一系列测试用例,包括不同类型的算术表达式,以验证程序的正确性。

例如:- 简单的四则运算表达式:2 + 3 * 4 - 5;- 包含括号的表达式:(2 + 3) * (4 - 5);- 包含多位数的表达式:12 + 34 * 56;- 包含浮点数的表达式:3.14 + 2.71828。

4. 性能测试和时间复杂度分析针对不同规模的输入数据,进行性能测试,记录程序的运行时间。

同时,分析算法的时间复杂度,验证算法的效率。

五、实验结果与分析我们设计并实现了一个栈的数据结构,并成功地完成了算术表达式求值的程序。

通过对一系列测试用例的验证,我们发现程序能够正确地求解各种类型的算术表达式,并返回正确的计算结果。

在性能测试中,我们对不同规模的输入数据进行了测试,并记录了程序的运行时间。

算术表达式求值实验报告

算术表达式求值实验报告

算术表达式求值实验报告1. 背景算术表达式求值是计算机科学中的基本问题之一,涉及到对数学表达式的解析和计算。

在计算机编程中,经常需要对用户输入的数学表达式进行求值,以得到正确的计算结果。

因此,研究如何高效地求解算术表达式是非常重要的。

在本次实验中,我们将探索不同方法来求解算术表达式,并比较它们的性能和准确性。

我们将使用Python语言作为实现工具,并通过编写代码来实现不同方法。

2. 分析2.1 表达式解析在进行表达式求值之前,我们首先需要对输入的数学表达式进行解析。

解析过程主要包括以下几个步骤:1.去除空格:将输入的字符串中的空格字符去除。

2.分词:将字符串按照运算符和操作数进行分割,得到一个由标记组成的列表。

3.构建语法树:根据分词结果构建一个语法树,用于表示数学表达式的结构。

4.求值:通过遍历语法树并执行相应操作,最终得到表达式的值。

2.2 求值方法在本次实验中,我们将尝试以下两种不同的求值方法:1.递归求值:通过递归地遍历语法树来求解表达式。

递归求值的优点是简单易懂,但可能存在性能问题。

2.栈求值:使用栈数据结构来辅助求解表达式。

栈可以有效地处理运算符的优先级和括号的匹配问题。

2.3 性能评估为了评估不同方法的性能,我们将使用一组测试用例来对其进行比较。

测试用例包括不同长度和复杂度的数学表达式,以及各种运算符和括号的组合。

我们将使用Python内置的time模块来测量每种方法的执行时间,并比较它们之间的差异。

此外,我们还将检查每种方法是否能正确地计算出表达式的结果。

3. 实验结果3.1 表达式解析在实现表达式解析过程时,我们首先去除输入字符串中的空格,并将其转换为一个字符列表。

然后,我们使用递归下降法来构建语法树。

具体而言,我们定义了以下几个函数:1.parse_expression(tokens):该函数接受一个标记列表作为参数,并返回一个表示整个表达式的语法树。

2.parse_term(tokens):该函数接受一个标记列表作为参数,并返回一个表示项的语法树。

数据结构表达式求值实验报告

数据结构表达式求值实验报告

实验二表达式求值
实验内容:
用算符优先法设计一个具有加、减、乘、除四功能的计算程序。

实验目的与要求:
掌握栈的数据结构和基本操作。

实验原理:
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.程序不够简洁,还有待改进,功能还有待更完善。

算术表达式求值数据结构实验报告

算术表达式求值数据结构实验报告

算法的正确性和效率分析
正确性
所有实现的数据结构都正确地实现了算术表达式求值的功能,没有出现计算错 误的情况。
效率
在处理大量数据时,使用堆栈(Stack)和队列(Queue)的数据结构表现最 佳。堆栈在处理后缀表达式时效率最高,而队列在处理中缀表达式时效率最高 。
数据结构优化的效果评估
使用哈希表(Hash Table)
展望未来,希望能够进一步研究算术 表达式求值算法的优化和改进,提高 计算效率和精度。
THANKS
感谢观看
05
列表(List)
数组(Array) 元组(Tuple) 集合(Set)
字典( Dictiona…
由于列表在Python中是动 态数组,其性能在处理大 量数据时相对较差。在算 术表达式求值中,列表的 平均执行时间最长。
使用NumPy库的数组结构 ,其性能在处理大量数据 时优于列表。但在算术表 达式求值中,其性能仍然 不如其他数据结构。
03
了解如何使用栈数据结构实现括号匹配和回退机制 。
掌握数据结构在算术表达式求值中的应用
01 熟悉使用数组、链表等基本数据结构存储和操作 算术表达式。
02 掌握如何使用树形数据结构表示算术表达式,如 二叉树或表达式树。
03 了解动态规划在优化算术表达式求值中的运用。
提高编程能力和解决问题的能力
01
在处理重复元素时,使用哈希表可以显著提高数据结构的效率。在算术表达式求值中,哈希表的使用可以减少重 复计算和查找的时间。
预处理输入数据
对输入的算术表达式进行预处理,如括号消除、指数化等,也可以提高数据结构的效率。预处理可以减少运算的 复杂度和时间。
05
实验总结
本次实验的收获和体会

数据结构表达式求值实验报告

数据结构表达式求值实验报告

数据结构表达式求值实验报告一、实验目的本次实验的主要目的是通过实现表达式求值的程序,深入理解数据结构和算法在解决实际问题中的应用。

具体包括掌握栈这种数据结构的操作和使用,熟悉表达式的转换和计算过程,提高编程能力和问题解决能力。

二、实验环境本次实验使用的编程语言为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.栈的定义、初始化、出栈进栈、取栈顶元素等步骤不难就先把结构打好了
2.操作数和运算符分别入不同的栈
char->int 进操作数栈
先考虑了小于10的整数直接进栈,重点是运算符的优先级这块函数的编写
3前面的都听简单的,就是小数编写这块想了很久,
将单个字符转为整数后还要定一个double p;使依次输入的数成一个小数->p.
}
//操作数栈初始化
void OPND_InitStack(Sqstack_OPND &s)
{
s.base=new SElemType_OPND[MAXSIZE];
if(!s.base)
printf("\n操作数栈存储分配失败!\n");
s.top=s.base;
s.stacksize=MAXSIZE;
if(ch != '.' )
{
if ( dimo != '.' )
{
p = p*10 ;
p += (ch-'0');
scanf("%c",&ch);
}
else if ( dimo == '.')
{
p = p+(ch-'0')*q;
q=q*q;;
scanf("%c",&ch#39;.' )
}
//操作数入栈
void OPND_Push(Sqstack_OPND &s,SElemType_OPND e)
{
if(s.top-s.base == s.stacksize)
printf("\n满栈!\n");

算术表达式实验报告

算术表达式实验报告

本科学生综合性实验报告项目组长:学号:成员:专业:计算机科学与技术班级:B02实验项目名称算术表达式求值指导教师及职称:开课学期2011-2012学年第一学期上课时间2011年10月15日-2011年11月5日一、实验设方案实验名称:算术表达式求值实验时间:2010年10月15 日小组合作:是●否○小组成员:0103356吴荣福0103316 倪志鹏1、实验目的实验目的:写代码来计算算术表达式2、实验思路(实验内容、数据处理方法及实验步骤等)#include <stdio.h>#include <stdlib.h>#include <conio.h>#define size 100#define addsize 20typedef int selemtype;typedef int status;typedef struct{selemtype *base;selemtype *top;int stacksize;}sqstack;//构造空栈status initstack(sqstack &l){l.base=(selemtype *)malloc(size*sizeof(selemtype));if(!l.base) exit(0);l.top=l.base;l.stacksize=size;return 1;}//返回栈顶元素status gettop(sqstack s){selemtype e;if(!s.top) return 0;e=*(s.top-1);return e;;}//进栈status push(sqstack &l,selemtype e){if(l.top-l.base>=l.stacksize){l.base=(selemtype*)realloc(l.base,l.stacksize+addsize*sizeof(selemtype));if(!l.base) exit(0);l.top=l.base+l.stacksize;l.stacksize+=addsize;}*l.top++=e;return 1;}//出栈status pop(sqstack &l,selemtype &e){if(l.top==l.base) return 0;e=*--l.top;return e;}//判断是不是运算符status ischar(char c){if(c=='+'||c=='-'||c=='*'||c=='/'||c=='#'||c=='('||c==')')return 1;elsereturn 0;}//判断优先级char youxian(char m,char n){int a,b;switch(m){case '+':case '-':a=6; break;case '*':case '/':a=9; break;case '(':a=5; break;case '#':a=-1; break;}switch(n){case '+':case '-':b=7; break;case '*':case '/':b=8; break;case ')':b=5; break;case '(':b=7;break;case '#':b=-1;break;}if(a>b)return '>';if(a<b)return '<';elsereturn '=';}//计算函数selemtype operate(selemtype a,selemtype m,selemtype b){ selemtype s;switch(m){case '+':s=(a+b);break;case '-':s=(a-b);break;case '*':s=(a*b);break;case '/':s=(a/b);break;}return s;}//主函数void main(){char ch[5];ch[0]='Y';do{printf("输入:\n");sqstack a,b;char c;selemtype x,y,theta;initstack(a); push(a,'#');initstack(b); c=getchar();while(c!='#' || gettop(a)!='#'){if(!ischar(c)){push(b,c-'0');c=getchar();}else{switch(youxian(gettop(a),c)){case '<':push(a,c);c=getchar();break;case '=':pop(a,x);c=getchar();break;case '>':pop(a,theta);pop(b,y);pop(b,x);push(b,operate(x,theta,y));break;}}}getchar();printf("结果是:");printf("%d\n",gettop(b));printf("是否继续(Y/N):");gets(ch);}while(ch[0]=='Y'||ch[0]=='y');printf("*************************\n");}指导老师对实验设计方案的意见指导老师签名:年月日二、实验结果与分析1、实验目的、实验思路。

算术表达式求值实习报告

算术表达式求值实习报告

算术表达式求值实习报告09040502班学号:052415 朱博凯一、需求分析(1)本程序需要用户自行输入表达式(运算符可以是加(+);减(-);乘(*);除(/);幂(^);括号(())),数字可以是整数也可以是浮点数,并按回车键结束!(2)程序功能:对算术表达式进行计算,输出结果,并输出其后缀表达式!(3)测试数据:8;1+2+3+4;88-1*3;1024/8*16;1024/(8*16);(22+3)*(8/2);3-3-3;8/(9-9);2*(5+3(2+4(3+6)))二、概要设计为实现上述程序功能,应以两个带头节点的栈分别存储表达式中的数和运算符。

1、栈的抽象数据类型定义ADT Stack{数据对象:d={ ai |ai∈elemset,i=1,2,3,......,n,n≥0}数据关系:r={<ai-1,ai,)>| ai-1,ai ∈d, i=2,3,......,n}约定a1为栈底,an 为栈顶。

基本操作:(1)InitStack(&S)操作结果:构造一个空栈S。

(2)DestroyStack(&S)初始条件:栈S已存在。

操作结果:销毁栈S。

(3)ClearStack(&S)初始条件:栈S已存在。

操作结果:将栈清空为空栈。

(4)StackEmpty(&S)初始条件:栈S已存在。

操作结果:若栈S为空栈,则返回TRUE,否则FALSE。

(5)StackLength(&S)初始条件:栈S已存在。

操作结果:返回栈的长度(或者说深度)。

(6)GetTop(S,&e)初始条件:栈S已存在且非空。

操作结果:用e返回S的栈顶元素。

(7)Push(&S,e)初始条件:栈S已存在。

操作结果:在栈顶插入新的元素e。

(8)Pop(&S,&e)初始条件:栈S已存在且非空。

操作结果:删除栈S的栈顶元素,并且用e返回它的值。

实验二--栈的应用---算术表达式的计算

实验二--栈的应用---算术表达式的计算

浙江大学城市学院实验报告课程名称数据结构与算法实验项目名称实验二栈的应用---算术表达式的计算实验成绩指导老师(签名)日期一.实验目的和要求1.进一步掌握栈的基本操作的实现。

2.掌握栈在算术表达式的计算方面的应用。

二. 实验内容1. 编写程序利用栈将中缀表达式转换成后缀表达式,即从键盘输入任一个中缀表达式(字符串形式),转换成后缀表达式后,将后缀表达式输出。

假设:中缀表达式包含圆括号( ) 及双目运算符+、-、*、/、^(乘方)。

要求:把栈的基本操作的实现函数存放在头文件stack1.h中(栈元素的类型为char),在主文件test6_2.cpp中包含将中缀表达式S1转换成后缀表达式S2的转换函数void Change( char *S1, char *S2 )及主函数,在主函数中进行输入输出及转换函数的调用。

2. 选做:编写利用栈对后缀表达式进行求值的函数double Compute(char *str),以计算从前述程序得到的后缀表达式的值。

要求:把栈的基本操作的实现函数存放在头文件stack2.h中(栈元素的类型为double),在主文件test6_2.cpp中添加后缀表达式求值函数,并在主函数中增加调用求值函数及输出结果值的语句。

3. 填写实验报告,实验报告文件取名为report2.doc。

4. 上传实验报告文件report2.doc与源程序文件stack1.h、stack2.h(若有)及test6_2.cpp到Ftp服务器上你自己的文件夹下。

二.函数的功能说明及算法思路(算法思路见源程序的注释部分)//栈的顺序存储结构定义struct Stack{ElemType *stack;int top;int MaxSize;};//初始化栈S为空void InitStack(Stack &S)//元素item进栈,即插入到栈顶void Push(Stack &S,ElemType item)//删除栈顶元素并返回ElemType Pop(Stack &S)//读取栈顶元素的值ElemType Peek(Stack &S)//判断S是否为空,若是则返回true,否则返回false bool EmptyStack(Stack &S)//清除栈S中的所有元素,释放动态存储空间void ClearStack(Stack &S)//将中缀算术表达式转换为后缀算术表达式void Change(char *S1,char *&S2)//返回运算符op所对应的优先级数值int Precedence(char op)//计算由str所指字符串的后缀表达式的值double Compute(char *str)四. 实验结果与分析五. 心得体会【附录----源程序】test6_2.cpp#include<iostream.h>#include<stdlib.h>#include<math.h>#include"stack1.h"#include"stack2.h"void main(){char x[30],y[30];double r;while(1){cout<<"请输入一个中缀算术表达式:";cin.getline(x,sizeof(x));Change(x,y);cout<<"对应的后缀算术表达式为:";cout<<y<<endl;r=Compute(y);cout<<"后缀算术表达式值为:"<<r<<endl<<endl;}}stack1.htypedef char ElemType1;struct Stack1{ElemType1 *stack;int top;int MaxSize;};void InitStack(Stack1 &S){S.MaxSize=10;S.stack=new ElemType1[S.MaxSize];if(!S.stack){cerr<<"动态储存分配失败"<<endl;exit(1);}S.top=-1;}void Push(Stack1 &S,ElemType1 item)if(S.top==S.MaxSize-1){int k=sizeof(ElemType1);S.stack=(ElemType1*)realloc(S.stack,2*S.MaxSize*k);S.MaxSize=2*S.MaxSize;}S.top++;S.stack[S.top]=item;}ElemType1 Pop(Stack1 &S){if(S.top==-1){cerr<<"Stack is empty! "<<endl;exit(1);}S.top--;return S.stack[S.top+1];}ElemType1 Peek(Stack1 &S){if(S.top==-1){cerr<<"Stack is empty! "<<endl;exit(1);}return S.stack[S.top];}bool EmptyStack(Stack1 &S){return S.top==-1;}void ClearStack(Stack1 &S){if(S.stack){delete []S.stack;S.stack=0;}S.top=-1;S.MaxSize=0;}//返回运算符op所对应的优先级数值int Precedence(char op){switch(op){case'+':case'-':return 1;case'*':case'/':return 2;case'^':return 3;case'(':case'@':default:return 0;}}//将中缀算术表达式转换为后缀算术表达式void Change(char *S1,char *S2){Stack1 R;InitStack(R);Push(R,'@');int i=0,j=0;char ch=S1[i];while(ch!='\0'){//对于空格字符不做任何处理,顺序读取下一个字符if(ch==' ')ch=S1[++i];//对于左括号,直接进栈else if(ch=='('){Push(R,ch);ch=S1[++i];}//对于右括号,使括号内的仍停留在栈中的运算符依次出栈并写入S2else if(ch==')'){while(Peek(R)!='(')S2[j++]=Pop(R);Pop(R);//删除栈顶的左括号ch=S1[++i];}//对于运算符,使暂存于栈顶且不低于ch优先级的运算符依次出栈并写入S2else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='^'){char w=Peek(R);while(Precedence(w)>=Precedence(ch)){S2[j++]=w;Pop(R);w=Peek(R);}Push(R,ch);//把ch运算符写入栈中ch=S1[++i];}else{if((ch<'0'||ch>'9')&&ch!='.'){cout<<"中缀表达式表示错误!"<<endl;exit(1);}while((ch>='0'&&ch<='9')||ch=='.'){S2[j++]=ch;ch=S1[++i];}S2[j++]=' ';}}//把暂存在栈中的运算符依次退栈并写入到S2中ch=Pop(R);while(ch!='@'){if(ch=='('){cerr<<"expression error!"<<endl;exit(1);}else{S2[j++]=ch;ch=Pop(R);}}S2[j++]='\0';}stack2.htypedef double ElemType2;struct Stack2{ElemType2 *stack;int top;int MaxSize;};void InitStack(Stack2 &S){S.MaxSize=10;S.stack=new ElemType2[S.MaxSize];if(!S.stack){cerr<<"动态储存分配失败"<<endl;exit(1);}S.top=-1;}void Push(Stack2 &S,ElemType2 item){if(S.top==S.MaxSize-1){int k=sizeof(ElemType2);S.stack=(ElemType2*)realloc(S.stack,2*S.MaxSize*k);S.MaxSize=2*S.MaxSize;}S.top++;S.stack[S.top]=item;}ElemType2 Pop(Stack2 &S){if(S.top==-1){cerr<<"Stack is empty! "<<endl;exit(1);}S.top--;return S.stack[S.top+1];}ElemType2 Peek(Stack2 &S){if(S.top==-1){cerr<<"Stack is empty! "<<endl;exit(1);}return S.stack[S.top];}bool EmptyStack(Stack2 &S){return S.top==-1;}void ClearStack(Stack2 &S){if(S.stack){delete []S.stack;S.stack=0;}S.top=-1;S.MaxSize=0;}//计算由str所指字符串的后缀表达式的值double Compute(char *str){Stack2 S;InitStack(S);double x,y;int i=0;while(str[i]){if(str[i]==' '){i++;continue;}switch(str[i]){case '+':x=Pop(S)+Pop(S);i++;break;case'-':x=Pop(S);x=Pop(S)-x;i++;break;case'*':x=Pop(S)*Pop(S);i++;break;case'/':x=Pop(S);if(x!=0)x=Pop(S)/x;else{cerr<<"Divide by 0!"<<endl;exit(1);}i++;break;case'^':x=Pop(S);x=pow(Pop(S),x);i++;break;default:x=0;while(str[i]>=48&&str[i]<=57){x=x*10+str[i]-48;i++;}if(str[i]=='.'){i++;y=0;double j=10.0;while(str[i]>=48&&str[i]<=57){y=y+(str[i]-48)/j;i++;j*=10;}x+=y;}}Push(S,x);}if(EmptyStack(S)){cerr<<"expression error!"<<endl;exit(1);}x=Pop(S);if(EmptyStack(S))return x;else{cerr<<"expression error!"<<endl;exit(1);}ClearStack(S);}(注:可编辑下载,若有不当之处,请指正,谢谢!)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《数据结构与数据库》实验报告实验题目算术表达式求值学院:化学与材料科学学院专业班级:09级材料科学与工程系PB0920603姓名:李维谷学号:PB09206285邮箱:**************指导教师:贾伯琪实验时间:2010年10月10日一、需要分析问题描述:表达式计算是实现程序设计语言的基本问题之一,它的实现是栈的应用的一个典型例子。

设计一个程序,演示通过将数学表达式字符串转化为后缀表达式,并通过后缀表达式结合栈的应用实现对算术表达式进行四则混合运算。

问题分析:在计算机中,算术表达式由常量、变量、运算符和括号组成。

由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。

因而在程序设计时,借助栈实现。

设置运算符栈(字符型)和运算数栈(浮点型)辅助分析算符优先关系。

在读入表达式的字符序列的同时完成运算符和运算数的识别处理,然后进行运算数的数值转换在进行四则运算。

在运算之后输出正确运算结果,输入表达式后演示在求值中运算数栈内的栈顶数据变化过程,最后得到运算结果。

算法规定:输入形式:一个算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)。

为使实验更完善,允许操作数为实数,操作符为(、)、.(表示小数点)、+、-、*、/、^(表示乘方),用#表示结束。

输出形式:演示表达式运算的中间结果和整个表达式的最终结果,以浮点型输出。

程序功能:对实数内的加减乘除乘方运算能正确的运算出结果,并能正确对错误输入和无定义的运算报错,能连续测试多组数据。

测试数据:正确输入:12*(3.6/3+4^2-1)#输出结果:194.4无定义运算:12*(3.6/(2^2-4)+1)# 输出结果:表达式出错,除数为0,无意义 错误输入:12+s# 输出结果:ERROR ! 二、 概要设计拟采用两种类型的展分别对操作数和操作符进行操作。

程序中将涉及下列两个抽象数据类型:1、设定“操作数”的栈的抽象数据类型定义: ADT SqStack_f{数据对象:D={i a },+∈∈N i R a i数据关系:R1={<1,-i i a a >|1-i a ,D a i ∈,i=2,…,n}约定n a 端为栈顶,i a 端为栈底。

基本操作:InitStack_f(&S)操作结果:构造一个空栈S 。

GetTop_f(&S,&e) 初始条件:栈S 已存在。

操作结果:用e 返回S 的栈顶元素。

Push_f(&S ,ch) 初始条件:栈S 已存在。

操作结果:插入元素ch 为新的栈顶元素。

Pop_f(&S,&e)初始条件:栈S 已存在。

操作结果:删除S 的栈顶元素,并以e 返回其值。

}ADT SqStack_f2、设定“操作符”的栈的抽象数据类型定义: ADT SqStack_c{数据对象:D={i a {}},'^'/'''*'''''+∈-+∈N i a i 数据关系:R1={<1,-i i a a >|1-i a ,D a i ∈,i=2,…,n}约定n a 端为栈顶,i a 端为栈底。

基本操作:InitStack_c(&S)操作结果:构造一个空栈S 。

GetTop_c(&S,&e) 初始条件:栈S 已存在。

操作结果:用e 返回S 的栈顶元素。

Push_c(&S ,ch) 初始条件:栈S 已存在。

操作结果:插入元素ch 为新的栈顶元素。

Pop_c(&S,&e) 初始条件:栈S 已存在。

操作结果:删除S 的栈顶元素,并以e 返回其值。

}ADT SqStack_c3、本程序包含六个模块1)主程序模块void main( ){初始化;while(命令==“继续”){接受数据;处理数据;接受命令;}}2)栈模块——实现栈抽象数据类型3)判断运算符优先级模块——判断运算符的优先级别4)后缀表达式转换模块——将中缀表达式转换为后缀表达式,方便操作5)无括号表示式求值运算模块——根据后缀表达式求值,并输出中间和最终结果6)运算结果输出模块——以正确形式输出表达式的值三、详细设计1、主程序中需要的全程量#define TTACK_INIT_SIZE 100 //初始分配最大空间量#define STACKINCREMENT 10 //(默认)增补空间量2、结点类型、指针类型typedef struct{float *base; //存储实型数据元素的一位数组float *top; //栈顶指针int stacksize; //栈数组容量}SqStack_f; //有序存储实型的顺序表类型typedef struct{char *base; //存储字符数据元素的一位数组char *top; //栈顶指针int stacksize; //栈数组容量}SqStack_c; //有序存储字符型的顺序表类型void InitStack_f(SqStack_f *s)void InitStack_f(SqStack_f *s)//构造一个存储实型(字符型)的空栈,预设空间为100,分配失败就退出void GetTop_f(SqStack_f *s,float *e)void GetTop_c(SqStack_c *s,char *e)//若栈s不空,则以e带值返栈顶元素,否则显示错误“ERROR”,并退出程序void Push_f(SqStack_f *s,float e)void Push_c(SqStack_c *s,char e)//在s的栈顶插入新的栈顶元素e,若栈的当前空间已满,则追加存储空间void Pop_f(SqStack_f *s,float *e)//若栈s不空,则删除栈s的栈顶元素,用e带值返回,否则退出程序其中部分操作的伪码算法(由于比较类似,以浮点型的栈为例)void InitStack_f(SqStack_f *s){//构造一个存储实型的空栈,预设空间为100,分配失败就退出s->base=(float *)malloc(TTACK_INIT_SIZE*sizeof(float));if(!s->base)exit(1);s->top=s->base;s->stacksize=TTACK_INIT_SIZE;}void GetTop_f(SqStack_f *s,float *e){//若栈s不空,则以e带值返栈顶元素,否则显示错误“ERROR”,并退出程序if(s->top==s->base){printf("ERROR!\n");exit(1);}*e=*(s->top-1);}{//在s的栈顶插入新的栈顶元素e,若栈的当前空间已满,则追加存储空间if(s->top-s->base>=s->stacksize){s->base=(float*)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(float));if(!s->base){printf("OVERFLOW!\n");exit(1);}s->top=s->base+s->stacksize;s->stacksize+=STACKINCREMENT;}*s->top++=e;}void Pop_f(SqStack_f *s,float *e){//若栈s不空,则删除栈s的栈顶元素,用e带值返回,否则退出程序if(s->top==s->base)exit(1);*e=*--s->top;}3、判断运算符优先级的算法:算符间的优先关系如下:伪码算法:int precede(char Top_char,char s1_char){//栈顶的运算符赋给Top_char,新读入的运算符赋给s1_char。

判断它们的优先级//若栈顶运算符优先级高,则返回1,否则返回0int i,pre[2];char op[2];op[0]=Top_char; //栈顶的运算符赋给op[0]op[1]=s1_char; //新读入的运算符赋给op[1]for(i=0;i<2;i++)switch(op[i]){case'(':case')':pre[i]=0;break; //将括号的优先级设为0case'+':case'-':pre[i]=1;break; //将+ - 运算符的优先级设为1case'*':case'/':pre[i]=2;break; //将* / 运算符的优先级设为2case'^':pre[i]=3;break; //将^ 运算符的优先级设为3}if(pre[0]>=pre[1]) //栈顶元素优先级高返回1return 1;elsereturn 0; //否则返回0}4、中缀表达式转换为后缀表达式的算法:算法过程描述:1)首先将左括号“(”压进栈,作为栈底元素;2)从左而右对算数表达式进行扫描,每次读入一个字符s1[i];3)若遇到数字或小数点,则立即写入s2[i],若遇算数运算符,将“”(空格)写入s2[i];4)遇到左括号“(”则压栈;5)若遇算术运算符,如果它们的优先级比栈顶元素高,则直接进栈,否则弹出栈顶元素输出到s2[i],直到新栈顶元素的优先级比它低,然后将它压栈;6)若遇到右括号“)”,则将栈顶元素输出到s2[i],直到栈顶元素为“(”,然后相互抵消;7)当扫描到“#”符号,表明表达式串已全部输入,将栈中的运算符全部输出到s2[i],并删除栈顶元素。

伪码算法:void Translate(char *s1){ //中缀表达式转换为后缀表达式char s2[80];SqStack_c Optr;int i=0,j=0;cha r t;InitStack_c(&Optr);//初始化一个存储字符型的空栈,便于存储运算符Push_c(&Optr,'(');// 首先将左括号“(”压进栈,作为栈底元素while(s1[i]!='#') //当扫描到的不是“#”,即表达式串没结束时{if(s1[i]>='0' && s1[i]<='9' || s1[i]=='.') //若果是数字或小数点则将其输出给s2[i]{s2[j++]=s1[i];if((s1[i+1]<'0' || s1[i+1]>'9') && s1[i+1]!='.')s2[j++]=' ';}elseswitch(s1[i]) //扫描到的是运算符{case'(':Push_c(&Optr,s1[i]);break;// 遇到左括号“(”则压栈case')':Pop_c(&Optr,&t); //若遇到右括号“)”,则将栈顶元素输出到s2[i]while(t!='(') //直到栈顶元素为“(”,然后相互抵消{s2[j++]=t;Pop_c(&Optr,&t);}break;default:while(GetTop_c(&Optr,&t),precede(t,s1[i])){//遇到算数运算符则比较优先级Pop_c(&Optr,&t);//栈顶元素优先级高,则弹出到s2[i]s2[j++]=t;}Push_c(&Optr,s1[i]);//栈顶元素优先级低,直接压栈}i++;}Pop_c(&Optr,&t);while(t!='(') //表达式串已结束,栈中的运算符全部输出到s2[i],并删除栈顶元素{s2[j++]=t;Pop_c(&Optr,&t);}for(i=0;i<j;i++) //将s2复制给s1s1[i]=s2[i];s1[i]= '#';s1[i+1]='\0';//为了方便打印后缀表达式,在字符串结尾加‘\0’}5、表示式求值运算的算法:算法描述:1)读入无括号的后缀表达式;2)若为数值和小数点则将其联合转换为浮点型后进栈(存放操作数);3)若为运算符,让栈顶元素和次顶元素与次运算符进行相应的运算,运算结果打印并进栈;4)重复2)3)步骤,直到输入为“#”,则此时栈中的结果便是所追求的表达式的值。

相关文档
最新文档