算术表达式求值演示Word下载.docx
《算术表达式求值演示Word下载.docx》由会员分享,可在线阅读,更多相关《算术表达式求值演示Word下载.docx(11页珍藏版)》请在冰豆网上搜索。
数据对象:
D={ai|ai∈CharSet,i=1,2,…,n,n≥0}
数据关系:
R1={<
ai-1,ai>
|ai-1,ai∈D,i=2,…,n}
基本操作:
InitStack(&
S)
操作结果:
构造一个空栈S。
GetTop(S,&
e)
初始条件:
栈S已存在。
若栈S不空,则以e返回栈顶元素。
Push(&
S,e)
在栈S的栈顶插入新的栈顶元素e。
Pop(&
S,&
删除S的栈顶元素,用e返回其值。
}ADTStack
2.设定运算表达式的抽象数据类型为:
ADTEvaluateExpression{
D={ai|ai为数字及运算符,i=1,2,…,n,n≥0}
R1={}
Precede(a1,a2)
字符a1,a2存在。
判定运算符的优先级
In(d)
字符d存在。
判断c是否为七种运算符之一
Operate(a,theta,b)
字符a,theta,b存在。
运算表达式结果。
}ADTEvaluateExpression
3.本程序包含3个模块:
(1)主程序模块:
intmain()
{
初始化;
do{
接受命令:
处理命令:
}
return0;
(2)栈模块——实现栈抽象数据类型
(3)求解算术表达式模块——实现算术表达式数据类型
各模块之间的调用关系如下:
主程序模块
↓
栈模块
求解算术表达式模块
三、详细设计
1.数据类型、字符类型。
typedefdoubleSElemType;
//数据类型
charPrecede(chara1,chara2)
{
charr;
//字符类型
2.栈类型
typedefstructSqStack{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
栈的基本操作设置如下:
voidInitStack(SqStack&
S)//构造一个空栈
boolGetTop(SqStackS,SElemType&
e)//若栈不空,则用e返回S的栈顶元素,并返回true;
否则返回false
boolPush(SqStack&
S,SElemTypee)//插入元素为e的新的栈顶元素
boolPop(SqStack&
S,SElemType&
e)//若栈不空,则删除S的栈顶元素,用e返回其值
其中部分操作的算法:
S,SElemTypee)
{//插入元素为e的新的栈顶元素
if(S.top-S.base>
=S.stacksize)
{//栈满,追加存储空间
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!
S.base)
exit(-1);
//存储空间分配失败
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
//top自增
returntrue;
if(S.top==S.base)
returnfalse;
e=*--S.top;
//删除一个元素,top减一
returntrue;
3.求解算术表达式的伪算法
SElemTypeEvaluateExpression(){
SqStackOPTR,OPND;
//OPTR和OPND分别为运算符栈和运算数栈
charc;
charData[20];
//定义此数组为了存放整数或小数
SElemTypea,b,d,e;
InitStack(OPTR);
//构造一个运算符栈
InitStack(OPND);
//构造一个运算数栈
Push(OPTR,'
\n'
);
//将换行符压入栈底
c=getchar();
GetTop(OPTR,e);
while(c!
='
||e!
)//栈顶不是换行符且输入不是换行符
{
if(In(c))//是符号则进栈
switch(Precede(e,c))
case'
<
'
:
//栈顶元素优先级低
Push(OPTR,c);
break;
//脱括号并接受下一字符
Pop(OPTR,e);
>
//退栈并将运算结果入栈
Pop(OPND,b);
Pop(OPND,a);
Push(OPND,Operate(a,e,b));
elseif(c>
0'
&
c<
9'
||c=='
.'
)
Push(OPND,c-48);
else
cout<
"
error!
输入错误!
endl;
GetTop(OPND,e);
returne;
4.主函数和其他函数的伪算法
intmain()//主程序
SElemTyperesult;
//初始定义
请输入表达式"
//输出输入要求
result=EvaluateExpression();
//执行函数操作命令
结果为:
result<
//输出结果
return0;
charPrecede(chara1,chara2)//判定运算符的优先级函数。
switch(a2)
+'
-'
//加减运算优先级相同
if(a1=='
('
||a1=='
r='
;
*'
/'
//乘除运算优先级相同
)'
括号匹配错误!
elseif(a1=='
没有左括号"
exit(-1);
switch(a1)
没有右括号"
default:
returnr;
boolIn(chard)//判断c是否为七种运算符之一的函数
switch(d)
5.函数的调用关系图反映了演示程序的结构层次:
主程序
↓————————↓————————↓
InitializationReadCommandInterpret
↓————————————————↓
InitEvaluateExpressionPrintEvaluateExpression
↓————————↓——————↓——————↓
InitStackPushPopGetTop
四、调试分析
1.这次作业思路比较简单,核心问题就是表达式的运算,要区分运算符的优先顺序。
通过运用栈后进先出的特点实现算法功能,调用push和pop等函数,实现一系列操作。
2.调试过程中,起初想打换行符时打成了’\’,忘了打字母n,结果程序调试总是有错误,改成’\n’后便成功运行了,可见,细节之处也很重要。
3.运用了很多的栈的基本操作,让我对栈的内容熟悉了不少,收获很大。
4.本题中时间复杂度为O(n)
五、用户手册
本程序的运行环境为DOS操作系统,执行文件为:
EvaluateExpression.exe。
六、测试结果
(1)请输入表达式:
3*(7-2);
结果为:
15
(2)请输入表达式:
8;
8
(3)请输入表达式:
1+2+3+4;
10
(4)请输入表达式:
88-1*5;
82
(5)请输入表达式:
1024*4/8;
512
(6)请输入表达式:
(20+2)*(6/2);
6
(7)请输入表达式:
3-3-3;
-3
(8)请输入表达式:
8/(9-9);
除数不能为零
(9)请输入表达式:
2*(6+2*(3+6*(6+6)));
312
(10)请输入表达式:
(((6+6)*6+3)*2+6)*2;
七、附录
源代码见“源程序文档”