
题目:算术表达式求值演示
班级:网络工程2班 姓名:陈智鸣 学号:1225112005 完成日期:2013.10.24
一、需求分析
1. 问题描述:表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的一个经
典例子。设计一个程序演示用算符优先法对算术表达式求值的过程。
2. 基本要求:利用教科书表3.1给出的算符优先关系,实现对算术四则混合运算表达式
的求值。
3. 测试数据:教科书例3-1的算术表达式3*(7-2)。
二、概要设计(算法描述)
基本操作:
InitStack_f(&S)
操作结果:构造一个空栈S。
GetTop_f(&S,&e)
初始条件:栈S已存在。
操作结果:用e返回S的栈顶元素。
Push_f(&S,ch)
初始条件:栈S已存在。
操作结果:插入元素ch为新的栈顶元素。
Pop_f(&S,&e)
初始条件:栈S已存在。
操作结果:删除S的栈顶元素,并以e返回其值。
}ADT SqStack_f
三、详细设计
代码如下:
#include #include using namespace std; int Operate(int x,char op,int y) //四则运算符的运算定义 { switch(op) { case'+': return x+y; case'-': return x-y; case'*': return x*y; case'/': return x/y; } } char Precede(char op1,char op2) //判断符号的优先级 { if(((op1=='+'||op1=='-')&&(op2=='+'||op2=='-'||op2==')'||op2=='#'))||((op1=='*'||op1=='/')&&(op2=='+'||op2=='-'||op2=='*'||op2=='/'||op2==')'||op2=='#'))) return '>'; if((op1=='('&&op2==')')||(op1=='#'&&op2=='#')) return '='; else return '<'; } void Tonumber(char &c,stack { int number=0; if(((c-'0')>=0&&(c-'0')<=9)) { while(((c-'0')>=0&&(c-'0')<=9)) { number=number*10+(c-'0'); cin>>c; } OPND.push(number); } } int main() { stack stack OPTR.push('#'); //出栈时的结尾判断 char c,op1,op2,op; int x,y,temp=1; cout<<"输入表达式,以'#'结束:"; cin>>c; while(c!='#'||OPTR.top()!='#') { Tonumber(c,OPND); if(c!='+'&&c!='-'&&c!='*'&&c!='/'&&c!='('&&c!=')'&&c!='#') { OPND.push(c); cin>>c; } else { op1=OPTR.top(); op2=c; switch(Precede(op1,op2)) { case '<': //栈顶元素优先级低 OPTR.push(c); cin>>c; break; case '=': //脱括号并接受下一个字符 OPTR.pop(); cin>>c; break; case '>': op=OPTR.top(); //退栈并将运算结果入栈 OPTR.pop(); x=OPND.top(); OPND.pop(); y=OPND.top(); OPND.pop(); OPND.push(Operate(y,op,x)); int a=OPND.top(); break; } } } cout<<"计算结果是:"< } 四、调试分析 1、 在编程过程中,为了增加程序的实用性,将程序适用范围扩大到了实数型,并增加了连续输入功能; 2、 在编程过程中,为了增加程序的健壮性,在运算除法时,考虑到除数为“0”时的报错和及时退出; 3、 在调试过程中,最初一下子出来程序就出错,为了方便检查错误,故在主函数中增加了检查后缀表达式是否转换正确的函数,并在每一步计算都跟踪结果是否正确; 4、 从程序实验题的编制过程中容易看出,线性表的广泛应用,特别是顺序存储结构的栈的应用。本题中涉及两元素类型(字符型和浮点型)的栈,由于是面向过程的语言,故只能分别定义。 五、用户手册 本程序只对实数的加减乘除乘方运算进行求值,且只对“()”这种形式的括号进行识别,“{}”或“[]”都不予以识别,表达式输入完后一定要加“#”表示输入结束。 六、测试结果
