算术表达式求值Word文档格式.doc
《算术表达式求值Word文档格式.doc》由会员分享,可在线阅读,更多相关《算术表达式求值Word文档格式.doc(31页珍藏版)》请在冰豆网上搜索。
3)4+26/12-2*7;
4)18-3*7-15/6;
5)2*(6+2*(3+6*(6+6)));
演示程序以用户与计算机交互方式执行,即在计算机终端上显示"
提示信息"
之后,由用户在键盘上输入演示程序中规定的运算命令;
相应的输入数据(滤去输入中的
非法字符)和运算结果显示在其后。
二、概要设计
(1)为实现上述程序功能需要的抽象数据类型:
1)栈的抽象数据类型:
ADTStack{
数据对象:
D={|ai|ai∈elemset,i=1,2,…,n,n≥0}
数据关系:
R1={<
ai-1,ai
>
|ai-1,ai∈D,i=2,…,n}
基本操作:
InitStack()
操作结果:
构造一个空栈。
GetTop(S,&
e)
初始条件:
栈S已存在且非空。
用e返回S的栈顶元素。
Push(&
S,e)
栈S已存在。
插入元素e为新的栈顶元素。
Pop(&
S,&
删除S的栈顶元素,并且用e返回其值。
}ADTStack
2)系统中子程序及功能要求:
Precede(charc1,charc2):
比较两个字符的优先级,并返回比较结果。
Operate(SElemTypea,charop,SElemTypeb):
函数进行四则运算,并返回运算结果。
judge(charop):
判断是否为运算符。
EvaluateExpression():
进行四则混合运算,并返回运算结果。
(2)本次程序设计中一共有三个模块,一个是由主函数构成的模块,一个是由各个子功能函数构成的栈模块,第三个是由运算等函数构成的运算模块。
(3)主模块可以对子模块中的函数进行调用,但子模块不能对主模块中的内容进行调用;
子模块中的函数可相互调用。
具体函数调用关系如下:
main
调用EvaluateExpression()
EvaluateExpression()
调用Precede、Operate、judge、InitStack()、
GetTop、Push、Pop。
三、详细设计
(1)程序流程图:
(2)元素类型、结点类型和指针类型
typedef
int
Status;
SElemType;
//元素类型
typedefstruct
{
SElemType
*base;
*top;
int
stacksize;
}SqStack;
//结点类型和指针类型
(3)栈的基本操作定义如下:
StatusInitStack(SqStack*S);
//构造一个空栈S
StatusGetTop(SqStackS)
//若栈不空,则返回栈顶元素,否则返回ERROR
StatusPush(SqStack*S,SElemTypee);
//插入e为新的栈顶元素
StatusPop(SqStack*S,SElemType*e);
//若栈不空,则删除S的栈顶元素,用e返回其值,返回OK,否则返回ERROR
(4)系统中子程序的基本操作定义:
CharPrecede(charc1,charc2);
//进行运算符的优先级比较,并返回比较结果。
SElemTypeOperate(SElemTypea,charop,SElemTypeb);
//进行两个整数数的四则运算,并返回运算结果。
Statusjudge(charop)
//判断是否为运算符。
SElemTypeEvaluateExpression()
//进行四则混合运算,并返回运算结果。
(5)部分基本操作的源程序如下:
StatusPush(SqStack*S,SElemTypee)
*(S->
top)++=e;
returnOK;
//插入元素e为新的栈顶元素
}
StatusPop(SqStack*S,SElemType*e)
if(S->
top==S->
base)
returnERROR;
//若栈为空,返回ERROR
*e=*(--(S->
top));
//栈不为空,删除S的栈顶元素,用e返回其值,并返回OK
charPrecede(chara,charb)
{//根据课本P53,表3-1算符间优先关系编写程序实现算符间的优先级比较
SElemTyper;
switch(a)
case'
+'
:
-'
//’+’,’-’运算符优先级相同,故放在一起进行比较
if(b=='
*'
||b=='
/'
('
)r='
<
'
;
elser='
break;
//’*’,’/’运算符优先级相同,故放在一起进行比较
)r='
#'
)
{
printf("
\nLogicexpressionerror!
Thereisnoright
bracket!
"
);
return(‘0’);
//逻辑错误,只有左括号,缺少右括号
else{
)'
='
\nMatchingerrorsinbrackets!
"
//括号匹配错误
\nLogicexpressionerror!
Thereisnoleft
bracket!
//逻辑错误,只有右括号,缺少左括号
else
return(r);
SElemTypeOperate(SElemTypea,charop,SElemTypeb)
{
//进行算数运算op为运算符
switch(op)
return(a+b);
return(a-b);
return(a*b);
if(b!
=0)return(a/b);
else
\n0cannotdoDivisor"
}
SqStackOPTR,OPND;
a,b,e,sum,theta,x;
charc;
//声明各个变量
sum=0;
//初始化
InitStack(&
OPTR);
//创建运算符栈
OPTR,('
0'
));
//’#’所对的整型量进运算符栈
OPND);
//创建操作数栈
c=getchar();
while(c!
||GetTop(OPTR)!
=('
))
if(!
judge(c))
while(c>
&
c<
9'
sum=(sum*10+(c-'
OPND,sum);
//不是运算符进栈
switch(Precede((GetTop(OPTR)+'
),c))
//栈顶元素优先级低
OPTR,(c-'
//托括号并接受下一个字符
OPTR,&
x);
//栈顶元素优先级高,退栈并将运算结果进栈
theta);
OPND,&
b);
a);
e=Operate(a,(theta+'
),b);
OPND,e);
OPND,0);
c='
//逻辑错误,0进栈,并结束运算
return(GetTop(OPND));
}
四、调试分析
(1)在调试过程中遇到的两大问题:
1)如何进行超过一位的数的存储
原因分析:
按照预想的想法,对表达式进行实际操作时发现,当输入超过一位的数时,在程序的运行过程中,只进行了数的最低位的运算:
例如1+15#,由于系统将15进行两个字符处理后仍按两个字符进行进栈存储,使得实际运行结果为6,显然是错误的
解决方案:
对操作数的进栈存储程序进行优化,使其能将多位数视为单个字
符进行进栈存储
具体程序由原来的if(!
judge(c))
优化如下:
while(c