算术表达式求值.docx
《算术表达式求值.docx》由会员分享,可在线阅读,更多相关《算术表达式求值.docx(29页珍藏版)》请在冰豆网上搜索。
![算术表达式求值.docx](https://file1.bdocx.com/fileroot1/2022-11/16/db0c9109-bc91-41e2-b678-b99671c6e108/db0c9109-bc91-41e2-b678-b99671c6e1081.gif)
算术表达式求值
《数据结构》
课程设计说明书
题目
算术表达式求值
学号
姓名
指导教师
日期
内蒙古科技大学课程设计任务书
课程名称
数据结构课程设计
设计题目
算术表达式求值
指导教师
时间
2013年秋学期第15周至第19周
一、教学要求
1.掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力
2.初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能
3.提高综合运用所学的理论知识和方法独立分析和解决问题的能力
4.训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风
二、设计资料及参数
每个学生在教师提供的课程设计题目中任意选择一题,独立完成,题目选定后不可更换。
算术表达式求值
以字符串表示算术表达式,在此基础上借助栈完成对表达式的转换和求值操作。
要求设计类(或类模板)来描述算术表达式及其操作,包含必要的构造函数和析构函数,以及其他能够完成如下功能的成员函数:
v输入算术表达式(中缀表示)
v中缀表达式转换为后缀表达式
v输出表达式
v对后缀表达式求值
并设计主函数测试该类。
三、设计要求及成果
1.分析课程设计题目的要求
2.写出详细设计说明
3.编写程序代码,调试程序使其能正确运行
4.设计完成的软件要便于操作和使用
5.设计完成后提交课程设计报告
四、进度安排
资料查阅与讨论(1天)
系统分析(2天)
系统的开发与测试(5天)
编写课程设计说明书和验收(2天)
五、评分标准
1.根据平时上机考勤、表现和进度,教师将每天点名和检查
2.根据课程设计完成情况,必须有可运行的软件。
3.根据课程设计报告的质量,如有雷同,则所有雷同的所有人均判为不及格。
4.根据答辩的情况,应能够以清晰的思路和准确、简练的语言叙述自己的设计和回答教师的提问
六、建议参考资料
1.《数据结构(C语言版)》严蔚敏、吴伟民主编清华大学出版社2004.11
2.《数据结构课程设计案例精编(用C/C++描述)》,李建学等编著,清华大学出版社2007.2
3.《数据结构:
用面向对象方法与C++语言描述》,殷人昆主编, 清华大学出版社2007.6
第1章
需求分析
1.1题目描述
以字符串表示算术表达式,在此基础上借助栈完成对表达式的转换和求值操作。
要求设计类(或类模板)来描述算术表达式及其操作,包含必要的构造函数和析构函数,以及其他能够完成如下功能的成员函数:
输入算术表达式(中缀表示)
中缀表达式转换为后缀表达式
输出表达式
对后缀表达式求值
并设计主函数测试该类。
1.2设计需求分析
根据题目要求,编译系统计算中缀表达式的过程分为两步:
(1)将中缀表达式后缀表达式;
(2)根据后缀表达式计算出表达式的值。
在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。
因而在程序设计时,借助栈实现。
算法输入:
一个算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)。
为简化,规定操作数只能为正整数,操作符为+、-*、/。
算法输出:
输出后缀表达式和后缀运算结果。
算法要点:
设置运算符栈和运算数栈辅助分析算符优先关系。
在读入表达式的字符序列的同时,完成运算符和运算数的识别处理,然后根据栈后进先出的特点不断进行入栈出栈转化成后缀表达式,然后再对后缀表达式进行相应运算。
1.3详细分析
要对一个含有加减乘除四则运算的合法的算术表达式进行求值,首先,应了解算术表达式的四则运算的规则:
(1)从左向右计算
(2)先乘除,后加减
(3)先括号内,后括号外
由此可知,比如算术表达式(7+15)*(23-28/4)的计算顺序,即为
(7+15)*(23-28/4)=22*(23-28/4)=22*(23-7)=22*16=352
其次,应明确“算符优先法”的内容:
算符优先法就是根据上述四则运算规则确定的优先关系来实现对表达式的编译或解释执行的。
一个简单的四则运算表达式由操作数(operand)、运算符(operator)和界限符(delimiter)组成,其中操作数是正整数,运算符只含加、减、乘、除四种,界限符有左右括号和表达式起始、结束符“#”;而且,为了统一算法的描述,将运算符和界限符通称为算符。
算符集OP={+,-,*,/,(,),#}。
根据上述3条运算规则,在具体的运算的每一步中,任意两个相继出现的算符θ1和θ2之间的优先关系只能是如下3中关系之一:
θ1<θ2θ1的优先级低于θ2
θ1=θ2θ1的优先级等于θ2
θ1>θ2θ1的优先级高于θ2
下表定义了算符之间的这种优先关系。
表1.1算符之间的优先关系
θ1θ2
+
-
*
/
(
)
#
+
>
>
<
<
<
>
>
-
>
>
<
<
<
>
>
*
>
>
>
>
<
>
>
/
>
>
>
>
<
>
>
(
<
<
<
<
<
=
)
>
>
>
>
>
>
#
<
<
<
<
<
=
第2章总体设计
2.1任务与分析
中缀输入,然后中缀表达式转化成后缀形式。
后缀表达式的操作数与中缀表达式的操作数先后次序相同,只是运算符的先后次序发生了改变。
因此,对中缀表达式从左到右依次进行扫描,每读到一个操作数即把它作为后缀的一部分输出;每读到一个运算符就将它和下一个运算符进行比较,根据运算符的优先级来决定它是入栈还是出栈。
后缀求值,通过ASC依次辨别然后计算。
2.2程序的主要功能
2.2.1中缀表达式转化成后缀表达式
描述:
(1)输入中缀表达式;
(2)扫描中缀表达式,通过调用比较运算符优先级依次输出。
代码表示:
//中缀转后缀
voidoperation(vector&exp1)
{
intmm=1;
ListStacks2;//通过栈正确输出运算符顺序
s2.push('#');
charc;
cin>>c;
while(c!
='#')
{
if(JudgeType(c))
{
if(mm==2)
{
exp1.push_back(',');
}
exp1.push_back(c);
mm=1;
c=getchar();
}
else
{
switch(judgeop(s2.GetTop(),c))
{
case'>':
s2.push(c);
c=getchar();
break;
case'=':
s2.pop();
c=getchar();
break;
case'<':
{
chartemat=s2.pop();
exp1.push_back(',');
exp1.push_back(temat);
break;
}
}
mm=2;
}
}
charname=s2.pop();
while(name!
='#')
{
exp1.push_back(',');
exp1.push_back(name);
name=s2.pop();
}
}
2.2.2后缀表达式求值
描述:
(1)设置一个指针用来遍历后缀表达式;
(2)通过符号的ASC码辨别数字和运算符;
(3)计算。
代码表示:
//计算后缀表达式
voidResult(vector&exp1)
{
ListStacks1;
intmm=1;
for(vector:
:
iteratoriter=exp1.begin();iter!
=exp1.end();++iter)
{
if(*iter>=48&&*iter<=57)
{
doublenum;
num=(double)*iter-48;
if(mm==0)
{
doublenn=s1.pop();
num=nn*10+num;
}
s1.push(num);
mm=0;
}
elseif(*iter==44)
{
mm=1;
continue;
}
elseif(*iter!
=44&&*iter<48)
{
doublere2=s1.pop();
doublere1=s1.pop();
s1.push(operate(re1,re2,*iter));
mm=1;
}
}
cout<}
2.3总体功能设计
函数主体结构与功能实现如下图2.1所示:
图2.1
第3章抽象数据类型定义
3.1链表栈的抽象数据类型的设计
ADT描述
ADTListStack{
数据对象D:
D={ai|ai∈ElemSet,i=1,2,3……,n,n≥0}
数据关系:
R1={|ai-1,ai∈D,i=1,2,3,……,n}约定an端为栈顶,a1端为栈底
基本操作:
ListStack()
操作结果:
构造一个空栈。
push(Tele)
初始条件:
栈已存在。
操作结果:
插入新元素为栈顶。
pop()
初始条件:
栈已存在且非空。
操作结果:
删除栈顶元素。
GetTop()
初始条件:
栈已存在且非空。
操作结果:
返回栈顶。
}ADTListStack
第4章详细设计
4.1工程视图
一个源代码文件,截取工程文件视图,由图4.1表示
图4.1工程视图
4.2类图视图
这个文件包含类、存储结构及一些重要函数函数,下面用截图来说明。
图4.2类图
4.3函数的调用关系
如下图4.3所示
图4.3函数调用关系
4.4主程序流程图
如图4.4所示:
图4.4主程序流程图
4.5主要算法代码
1.中缀转化成后缀
voidoperation(vector&exp1)
{
intmm=1;
ListStacks2;//通过栈正确输出运算符顺序
s2.push('#');
charc;
cin>>c;
while(c!
='#')
{
if(JudgeType(c))
{
if(mm==2)
{
exp1.push_back(',');
}
exp1.push_back(c);
mm=1;
c=getchar();
}
else
{
switch(judgeop(s2.GetTop(),c))
{
case'>':
s2.push(c);
c=getchar();
break;
case'=':
s2.pop();