算术表达式求值.doc

上传人:b****1 文档编号:167449 上传时间:2022-10-05 格式:DOC 页数:31 大小:227.50KB
下载 相关 举报
算术表达式求值.doc_第1页
第1页 / 共31页
算术表达式求值.doc_第2页
第2页 / 共31页
算术表达式求值.doc_第3页
第3页 / 共31页
算术表达式求值.doc_第4页
第4页 / 共31页
算术表达式求值.doc_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

算术表达式求值.doc

《算术表达式求值.doc》由会员分享,可在线阅读,更多相关《算术表达式求值.doc(31页珍藏版)》请在冰豆网上搜索。

算术表达式求值.doc

算术表达式求值演示

一、需求分析

(1)输入的形式:

语法正确的、不含变量的字符序列形式的整数表达式

输入值的范围:

整数的范围是-(215-l)~(215-1)

运算符:

+,-,*,/,(,)

表达式结束运算符#

(2)输出的形式:

范围是-(215-l)~(215-1)的整数

(3)程序所能达到的功能:

实现对算术四则混合运算表达式的求值;

程序执行命令包括:

1) Calculate  ——计算表达式的值

2) Exit    ——退出

(4)测试数据

1)8

2)2-2-2-3;

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∈D,i=2,…,n}

基本操作:

InitStack()

操作结果:

构造一个空栈。

GetTop(S,&e)

初始条件:

栈S已存在且非空。

操作结果:

用e返回S的栈顶元素。

Push(&S,e)

初始条件:

栈S已存在。

操作结果:

插入元素e为新的栈顶元素。

Pop(&S,&e)

初始条件:

栈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;

typedef int SElemType; //元素类型

typedefstruct

{

SElemType *base;

SElemType *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)); 

returnOK; //栈不为空,删除S的栈顶元素,用e返回其值,并返回OK

}

charPrecede(chara,charb)

{//根据课本P53,表3-1算符间优先关系编写程序实现算符间的优先级比较

SElemTyper;

switch(a)

{

case'+':

case'-':

  //’+’,’-’运算符优先级相同,故放在一起进行比较

if(b=='*'||b=='/'||b=='(')r='<';

elser='>';

break;

case'*':

  //’*’,’/’运算符优先级相同,故放在一起进行比较

case'/':

if(b=='(')r='<';

elser='>';

break;

case'(':

if(b=='#')

{

printf("\nLogicexpressionerror!

Thereisnoright

bracket!

");

return(‘0’);//逻辑错误,只有左括号,缺少右括号

}

else{

if(b==')')r='=';

elser='<';

}

break;

case')':

if(b=='(')

{

printf("\nMatchingerrorsinbrackets!

");

return(‘0’);  //括号匹配错误

}

elser='>';

break;

case'#':

if(b==')')

{

printf("\nLogicexpressionerror!

Thereisnoleft

bracket!

"); 

return(‘0’); //逻辑错误,只有右括号,缺少左括号

}

else

{

if(b=='#')r='=';

elser='<';

}

break;

}

return(r);

}

SElemTypeOperate(SElemTypea,charop,SElemTypeb)

{  //进行算数运算op为运算符

switch(op)

{

case'+':

return(a+b);break;

case'-':

return(a-b);break;

case'*':

return(a*b);break;

case'/':

if(b!

=0)return(a/b);

else

{

printf("\n0cannotdoDivisor");

return(‘0’);       

}

}  

}

SElemTypeEvaluateExpression()

{

SqStackOPTR,OPND;

SElemType a,b,e,sum,theta,x;      

charc;             //声明各个变量

sum=0;             //初始化

InitStack(&OPTR);        //创建运算符栈

Push(&OPTR,('#'-'0'));     //’#’所对的整型量进运算符栈

InitStack(&OPND);        //创建操作数栈

c=getchar();          

while(c!

='#'||GetTop(OPTR)!

=('#'-'0'))

{

if(!

judge(c))        

{

while(c>='0'&&c<='9')

{

sum=(sum*10+(c-'0'));

c=getchar();

}

Push(&OPND,sum);      //不是运算符进栈

sum=0;

}

else

switch(Precede((GetTop(OPTR)+'0'),c)) 

{

case'<':

   //栈顶元素优先级低

Push(&OPTR,(c-'0'));c=getchar();break;

case'=':

   //托括号并接受下一个字符

Pop(&OPTR,&x);c=getchar();break;

case'>':

   //栈顶元素优先级高,退栈并将运算结果进栈 

Pop(&OPTR,&theta);

Pop(&OPND,&b);

Pop(&OPND,&a);

e=Operate(a,(theta+'0'),b);

Push(&OPND,e);

break;

case'0':

Push(&OPND,0);c='#'; //逻辑错误,0进栈,并结束运算

break;

}   

}

return(GetTop(OPND));

}

四、调试分析

(1)在调试过程中遇到的两大问题:

1)如何进行超过一位的数的存储

原因分析:

按照预想的想法,对表达式进行实际操作时发现,当输入超过一位的数时,在程序的运行过程中,只进行了数的最低位的运算:

例如1+15#,由于系统将15进行两个字符处理后仍按两个字符进行进栈存储,使得实际运行结果为6,显然是错误的

解决方案:

对操作数的进栈存储程序进行优化,使其能将多位数视为单个字

符进行进栈存储

具体程序由原来的if(!

judge(c))

{

Push(&OPND,sum);

c=getchar();

优化如下:

if(!

judge(c))        

{

while(c

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 党团建设

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1