逆波兰表达式求值实验报告湖大
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
HUNAN UNIVERSITY 课程实习报告
题目:逆波兰表达式求值
学生姓名范舜奕
学生学号20100820608
专业班级通信6班
指导老师吴帆
完成日期 2012.04. 07
实验二逆波兰表达式求值
★问题描述
选一个后缀表达式,利用堆栈来计算该表达式的值,同时要效验后缀表达式是否正确★基本要求
(1)从键盘中输入一个后缀表达式,该表达式包括加减乘除的操作符,一级正整数作为操作数等
(2)用堆栈来表示
★输入输出格式
输入:在字符界面上输入一个后缀表达式,其中两相邻操作数之间利用空格隔开。
以“#”表示结束。
输出:如果该后缀表达式正确,那么在字符界面上输出其结果,计算结果小数点后面保留两位有效数字。
如果不正确,请在字符界面上输出表达式错误提示
★测试用例
输入:2 3 * 1 -#
输出:5
★设计思路
◆为了测试需要,应以浮点数存储输入和输出,利用堆栈来实现算法。
栈的抽象数据类型的定义如下:
ADT Stack {
数据对象:D={a i| a i∈ElemSet, i=1,2,...,n, n≥0 }
数据关系:R={<a i-1 , a i >| a i-1 ,a i∈D, i=2,...,n}
基本操作:
InitStack(&S)
操作结果:构造一个空栈S
DestoryStack(&S)
初始条件:栈S已存在
操作结果:栈S被销毁
Pop(&S,e)
初始条件:栈S已存在且非空
操作结果:删除S的栈顶元素,并用e返回其值
Push(&S,e)
初始条件:栈S存在且非空
操作结果:插入元素e为新的栈顶元素
StackLength(&S)
初始条件:栈S已存在
操作结果:返回S的元素的个数,即栈的长度
} ADT LinkLiSt
◆本程序包含三个基本模块
(1)主程序模块:元素进栈、出栈、删除栈顶元素、实现数字元素的运算
(2)线性表模块:实现栈的抽象数据类型
(3)元素结构单元模块:定义栈每个元素的结构
◆算法的基本思想:
定义堆栈的抽象数据类型,读取键盘上输入的数据,根据读取的输入调用入栈函数,判断输入的数据是否合法,通过switch_case结构判断输入运算符的种类,转而执行不同的处理代码。
★算法
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OVERFLOW -2
typedef float SElemtype;
typedef int Status;
typedef struct
{
SElemtype * base;
SElemtype * top;
int stacksize;
} SqStack;
Status InitStack(SqStack &S)
{
S.base = (SElemtype *)malloc(STACK_INIT_SIZE*sizeof(SElemtype));
if (! S.base) exit(OVERFLOW);
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}
int StackLength(SqStack S)
{
return S.top - S.base;
}
Status Push(SqStack &S, SElemtype e) {
*S.top++ = e;
return OK;
}
Status Pop(SqStack &S, SElemtype &e) {
if (S.top == S.base) return ERROR;
e = * -- S.top;
return OK;
}
Status IsDigital(char ch)
{
if(ch>='0'&&ch<='9')
{
return 1; //是数字字母
}
return 0; //不是数字字母
}
int EvalValue(char *ch, SqStack &S)
{
int i=0;
SElemtype result=0;
char a;
a=ch[i];
while(IsDigital(a))
{
result=10*result+(int)(a-48);
a=ch[++i];
}
Push(S, result);
return i;
}
void EvalExpr(char ch, SqStack &S)
{
SElemtype oper1,oper2;
if(StackLength(S)<2)
{
printf("\n表达式错误\n");
exit(0);
}
switch(ch)
{
case '+':
Pop(S, oper1);
Pop(S, oper2);
Push(S, oper1+oper2);
break;
case '-':
Pop(S, oper1);
Pop(S, oper2);
Push(S, oper2-oper1);
break;
case '*':
Pop(S, oper1);
Pop(S, oper2);
Push(S, oper1*oper2);
break;
case '/':
Pop(S, oper1);
Pop(S, oper2);
Push(S, oper2/oper1);
break;
/* case '%':
oper1=Stack_Pop(pStk);
oper2=Stack_Pop(pStk);
Stack_Push(pStk,oper2%oper1);
break;*/
default:
printf("error");
}
}
Status evaluate (char ch[], float & result)
{
SqStack S;
Status St;
int i;
i=0;
St = InitStack(S);
while(ch[i]!='#'&&i<100)
{
if(IsDigital(ch[i]))
{
i+=EvalValue(&ch[i], S);
}
else if(ch[i]==' ')
i++;
else{
EvalExpr(ch[i], S);
i++;
}
}
if(StackLength(S) ==1)
Pop(S, result);
else{
//printf("表达式错误");
return ERROR;
}
return OK;
}
main()
{
Status St;
//SqStack S;
char ch[100],c;
int i=0;
float result;
printf("请输入表达式。
#表示结束\n");
while(i<100)
{
scanf("%c",&c);
ch[i++]=c;
if(c=='#')
break;
}
St = evaluate (ch, result);
if (St)
printf("result is %5.2f \n", result);
else
printf("\n表达式错误\n");
system("pause");
return 0;
}
运行结果
★算法的时间复杂度:
整个程序的时间复杂度是O(n).
★实验心得
此次试验比上一次的实验有进步。
对于给出的算法,能够理解算法的含义。
因此在调试函数的时候,能够对运行时出现的问题进行改正。
对语法错误也能够纠正。
在程序的编写上,有较大的进步。
填空的时间也比上一次的要短很多。