算术表达式求值演示程序.docx
- 文档编号:373361
- 上传时间:2022-10-09
- 格式:DOCX
- 页数:20
- 大小:168.32KB
算术表达式求值演示程序.docx
《算术表达式求值演示程序.docx》由会员分享,可在线阅读,更多相关《算术表达式求值演示程序.docx(20页珍藏版)》请在冰豆网上搜索。
算术表达式求值演示程序
软件学院
课程设计报告书
课程名称数据结构
设计题目算术表达式求值演示程序
专业班级
学号
姓名
指导教师
2012年1月
1.设计时间2
2.设计目的2
3.设计任务2
4.设计内容2
4.1需求分析2
4.2总体设计2
4.2.1抽象数据类型的定义2
4.2.2函数模块说明3
4.2.3主函数流程图4
4.2.4函数模块调用关系5
4.2.5运算符间的优先关系5
4.3详细设计6
4.3.1数据类型的定义6
4.3.2函数调用关系8
4.3.3主要模块的算法描述8
4.4测试与分析10
4.4.1测试10
4.4.2分析11
4.5附录11
5.总结与心得体会16
参考文献17
成绩评定17
1设计时间
2012.1.4-2012.1.6
2设计目的
掌握栈的使用和把一个表达式翻译成能够正确求值的一个机器指令序列的原理。
3设计任务
设计一个程序,演示用算符优先法对算术表达式求值的过程。
4设计内容
4.1需求分析
1、程序所能达到的功能:
能够处理以字符序列的形式输入的不含变量的实数表达式,正确处理负数与小数,判断表达式是还语法正确(包含分母不能为零的情况),正确实现对算术四则混合运算表达式的求值,能够将计算中遇到的问题和结果以文件的形式予以存储。
2、输入的形式和输入值的范围:
以字符串的形式输入表达式,以“#”结束。
3、输出的形式:
在计算过程中遇到的问题或最终的答案将显示在屏幕上,同时所计算的表达式的最终的结果也将保存在文件中。
4、测试数据:
输入“3*(7-2)#”时,输出“15.000000”,测试正确;输入“!
(9-2)#”时,输出“输入错误!
”,测试正确。
4.2总体设计
4.2.1抽象数据类型定义
ADTStack{
数据对象:
D={
|
∈ElemSet,i=1,2,…,n,n≧0}
数据对象:
R1={<
>|
i=2,…,n}
约定
端为栈顶,
端为栈底。
基本操作:
InitStack(&S)
操作结果:
构造一个空栈S。
GetTop(S)
初始条件:
栈S已存在。
操作结果:
用P返回S的栈顶元素。
Push(&S,ch)
初始条件:
栈S已存在。
操作结果:
插入元素ch为新的栈顶元素。
Pop(&S)
初始条件:
栈S已存在。
操作结果:
删除S的栈顶元素。
In(ch)
操作结果:
判断字符是否是运算符,运算符即返回1。
Precede(c1,c2)
初始条件:
c1,c2为运算符。
操作结果:
判断运算符优先权,返回优先权高的。
Operate(a,op,b)
初始条件:
a,b为整数,op为运算符。
操作结果:
a与b进行运算,op为运算符,返回其值。
num(n)
操作结果:
返回操作数的长度。
EvalExpr()
初始条件:
输入表达式合法。
操作结果:
返回表达式的最终结果。
}ADTStack
4.2.2函数模块说明
为实现算符优先算法,可以使用两个工作栈。
一个称做OPTR,用以寄存运算符;另一个称做OPND,用以寄存操作数或运算结果。
算法的基本思想是:
(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈底元素
(2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为“#”)。
算法中还调用了两个函数。
其中Precede是判定运算符栈顶运算符θ1与读入的运算符θ2之间优先关系的函数;Operateo为进行二元运算aθb的函数,如果是编译表达式,则产生这个运算的一组相应指令并返回存放结果的中间变量名;如果是解释执行表达式,则直接进行该运算,并返回运算结果。
4.2.3主函数流程图
4.2.4函数模块调用关系
4.2.5运算符间的优先关系
θ1θ2
+
-
*
/
(
)
#
+
>
>
>
<
<
>
>
-
>
>
>
<
<
>
>
*
>
>
>
>
<
>
>
/
>
>
>
>
<
>
>
(
<
<
<
<
<
=
)
>
>
>
>
>
>
#
<
<
<
<
<
=
4.3详细设计
4.3.1数据类型的定义及基本操作
//=====ADTStack的表示与实现=====
//-----栈的顺序存储表示-----
#defineSTACK_INIT_SIZT100;
#defineSTACKINCREMENT10
typedefstruct{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
//-----基本操作的算法描述-----
StatusInitStack(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;
returnOK;
}
StatusGetTop(SqStackS,SElemType&e){
if(S.top==S.base)returnERROR;
e=*(S.top-1);
returnOK;
}
StatusPush(SqStack&S,SElemTypee){
if(S.top-S.base>=S.stacksize){
S.base=(SElemType*)realloc(S.base
(S.StackSize+STACKINCREMENT)*sizeof(SElemType));
if(!
S.base)exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
returnOK;
}
StatusPop(SqStack&S,SElemType&e){
if(S.top==S.base)returnERROR;
e=*--S.top;
returnOK;
}
OperandTypeEvaluateExpession(){
InitStack(OPTR);Push(OPTR,’#’);
InitStack(OPND);c=getchar();
while(c!
’#’||GetTop(OPTR)!
=’#’){
if(!
In(c,OP)){Push((OPND,c);c=getchar();)
else
switch(Precede(GetTop(OPTR),c)){
case’<’:
Push(OPTR,c);c=getchar();break;
case’=’:
Pop(OPTR,x);c=getchar();break;
case’>’:
Pop(OPTR,theta);Pop(OPND,b);Pop(OPND,a);
Push(OPND,Operate(a,theta,b));break;
}
}
}
4.3.2函数调用关系
4.3.3主要模块的算法描述
voidmain(){
SqStack_TOPTR;SqStack_NOPND;
floata,b,i;chartheta,c,x;
InitStack_T(&OPTR);Push_T(&OPTR,’#’);
InitStack_N(&OPND);
printf(“请输入表达式关以’#’结尾:
\n”);
c=getchar();
if(c==35||(c>=40&&c<=43)||c==45||(c>=47&&c<=57))
{
while(c!
=’#’||GetTop_T(&OPTR)!
=’#’)
{
if(c>=48&&c<=57)
{
i=(float)c-48;
Push_N(&OPND,i);
c=getchar();
}
else
{
switch(Precede(GetTop_T(&OPND),c))
{
case’<’:
Push_T(&OPTR,c);c=getchar();break;
case’=’:
x=Pop_T(&OPTR);c=getchar();break;
case’>’:
theat=Pop_T(&OPTR);b=Pop_N(&OPND);
a=Pop_N(&OPND);Push_N(&OPND,Operate(a,theta,b));
break;
}
}
}
printf(“结果是%f\n”,GetTop_N(&OPND));
}
elseprintf(“输入错误!
\n”);
}
4.4测试与分析
4.4.1测试
加法测试,输入正确,输出正确,测试正确:
减法测试,输入正确,输出正确,测试正确:
乘法测试,输入正确,输出正确,测试正确:
除法测试,输入正确,输出正确,测试正确:
输入表达式正确,输出正确,测试正确:
输入表达式错误,能正确判断,测试正确:
4.4.2分析
内容包括:
1、调试过程中遇到的问题是如何解决的以及对设计与实现的回顾讨论和分析:
遇到的问题:
调试过程中遇到了输入非法字符不输出“错误!
”的情况。
解决的办法:
查ASCII码表得知运算符’+’,’-‘,’*’,’/’,’(‘,’)’,’#’和运算数’0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’相应的ASCII值。
在主程序中加入了判断语句,判断输入的是否为运算符或运算数。
如果是,则进行正常运算;如果不是,则返回错误。
2、算法的时间复杂度和空间复杂度的分析:
中缀表达式运算时间主要用在字符串扫描和算符优先权的比较上。
把#看作运算符,操作数与运算符个数相同,最坏情况下优先级比较是n/2次,即运算顺序完全是逆序的,每个字符扫描一遍是O(n)的,所以整个算法复杂度是O(n2)的。
算法中用到两个栈,分别为O(n/2),其算法空间复杂度是O(n)。
4.5附录
#include"stdio.h"
#include"stdlib.h"
#defineOK1
#defineERROR0
#defineOVERFLOW0
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
typedefstruct{
char*base;
char*top;
intstacksize;
}SqStack_T;
typedefstruct{
float*base;
float*top;
intstacksize;
}SqStack_N;
voidInitStack_T(SqStack_T*S){
(*S).base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算术 表达式 求值 演示 程序
![提示](https://static.bdocx.com/images/bang_tan.gif)