数据结构课程设计带括号的算术表达式求值Word下载.docx
《数据结构课程设计带括号的算术表达式求值Word下载.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计带括号的算术表达式求值Word下载.docx(15页珍藏版)》请在冰豆网上搜索。
Pop();
//出栈操作
GetHead();
//返回栈中的最顶层元素
MakeEmpty();
//清空栈操作
Calculatormethod:
Calculator();
//计算主体
celarstream();
//清空输入流
Prior();
//返回运算符的优先级
done();
//做一次二元运算
output();
//打印结果并输出
EnEmpty();
//调用MakeEmpty(),并清空栈
2.cpp文件
Calculator.cpp
Method:
intmain();
//主程序
3.程序流程图
开始
优先级比较算法
Data算法
建立栈
存放操作字符
存放数据
调用Calculator()
计算
结束
4.功能描述
(1)所有函数都是在calculator()函数为主体,调用其他函数开始的。
Calculator函数让输入的中缀表达式按字符读取。
(2)如果读取为操作数,则将字符返回输入流(cin.putback),读操作数并进data栈,然后读入下一字符送入ch。
(3)如果读取为操作符,则判断操作符类型,确定优先级。
不同的优先数的操作符进行不同的运算。
(4)用output函数进行结果等的输出。
(5)Enempty为清空两个栈。
(6)主函数调用时,创建calculator实例,调用calculator函数进行计算,然后调用output函数进行输出,最后调用enempty清空栈。
注:
程序有两个栈,分别为data和sign。
分别存放操作数和操作符;
此程序要求输入的是中缀表达式,即直接对中缀表达式求值,不用转化为后缀在求值。
五、源程序清单:
#include<
iostream.h>
string.h>
stdio.h>
stdlib.h>
assert.h>
#defineERROR-1
#defineBLANK0
#defineDATA1
#defineKUOHAO15
#defineKUOHAO22
#defineADD_OR_SUB3
#defineMUT_OR_DIV4
constintsize=500;
template<
classElem>
classStack;
classStackNode//堆栈的结点类
{
friendclassStack<
Elem>
;
Elemelem;
StackNode<
*link;
StackNode(Eleme=0,StackNode<
*l=NULL):
elem(e),link(l)
{
//cout<
<
"
elemis:
"
e<
endl;
}
};
classStack
intnumber;
*head;
public:
Stack():
number(0),head(NULL){}
~Stack()
*tmp=head;
while(head!
=NULL)
head=head->
link;
deletetmp;
tmp=head;
voidPush(constElem&
e)
number++;
head=newStackNode<
(e,head);
voidMakeEmpty()
number=0;
voidPop()
assert(number!
=0);
number--;
ElemGetHead()
returnhead->
elem;
intGetNumber()const{returnnumber;
}//返回堆栈中元素的数目
classCalculator
private:
Stack<
double>
data;
//数据栈
char>
sign;
//运算符栈
intflag;
//标志位表示前一个输入的是数还是一个运算符
Calculator()
flag=BLANK;
~Calculator(){}
intPrior(charch)const//返回运算符的优先级
switch(ch)
case'
)'
:
return1;
+'
-'
return2;
case'
*'
/'
return3;
('
return5;
default:
return-1;
voidclearstream()//清空输入流
charch;
while(cin>
>
ch,ch!
='
'
);
}
voiddone(charch)//做一次二元运算
doublea,b;
a=data.GetHead();
data.Pop();
b=data.GetHead();
b+=a;
break;
b-=a;
b*=a;
if(a==0)
{cout<
除数为零!
返回系统默认值如下"
b/=a;
default:
break;
data.Push(b);
voidCalculate()
doubled;
)
{
if(ch>
0'
&
&
ch<
9'
||ch=='
.'
)
if(flag==DATA)
{cout<
\nErrorinput!
小数点只能有一位!
flag=ERROR;
clearstream();
return;
cin.putback(ch);
cin>
d;
data.Push(d);
flag=DATA;
else//如果输入的是字符,则作出判断
intprio=Prior(ch);
chartempch,chprior;
switch(prio)
case-1:
cout<
不允许的字符"
case1:
//如果是一个后括号,
tempch=sign.GetHead();
//是合法的运算,取一个运算符
flag=KUOHAO2;
while(tempch!
)//做完这一重括号内的所有运算
sign.Pop();
done(tempch);
if(sign.GetNumber()!
=0)
sign.Pop();
case2:
//如果读入的是一个+或者-号,
//如果+前面没有数据,或者+是被写在括号里的,则向//它的前面压入一个0到data
if(flag==BLANK||data.GetNumber()==0||flag==KUOHAO1)
data.Push(0);
//push0tostack
//sign.Push(ch);
//push+/-tostack
//如果它前面是一个后括号,因后括号里的内容已经做过//运算,故只当一个一般的来做
if(flag==KUOHAO2||flag==DATA)
while(sign.GetNumber()&
sign.GetHead()!
Prior(sign.GetHead())>
=Prior(ch))
done(sign.GetHead());
flag=ADD_OR_SUB;
sign.Push(ch);
case3:
//如果当前输入是一个*或者/号
//如果前一个输入是一个*或者/号
//如果它前面不只一个数字,则做它前面的运算
if(data.GetNumber()!
=1)
chprior=Prior(sign.GetHead());
if(chprior>
=Prior(ch)&
chprior=sign.GetHead();
done(chprior);
sign.Push(ch);
flag=MUT_OR_DIV;
case5:
//如果当前的是一个前括号
//如果它前面输入的是一个数据,则提示出错
if(flag==DATA)
\n输入错误!
数据后不能直接跟括号!
sign.Push(ch);
flag=KUOHAO1;
非法字符!
ch<
if(sign.GetNumber()&
sign.GetHead()=='
)
cout<
\n括号不配对!
//前括号没有找到后括号
return;
if(flag==MUT_OR_DIV||flag==ADD_OR_SUB)
\n表达式没有写完!
endl;
while(sign.GetNumber())
if(sign.GetHead()=='
\n括号不配对!
flag=ERROR;
done(sign.GetHead());
voidOutPut()
\nTheansweris:
data.GetHead()<
voidEnEmpty()
data.MakeEmpty();
sign.MakeEmpty();
Calculator.cpp
#include"
StackNode.h"
Calculator.h"
intmain()
chariscontinue='
Y'
Calculatorcal;
while(iscontinue=='
cout<
************************************************"
请输入你要计算的中缀表达式,以等号结束:
cal.Calculate();
cal.OutPut();
cal.EnEmpty();
是否继续(Y/N)?
cin>
iscontinue;
iscontinue=toupper(iscontinue);
六、运行结果:
正常情况:
异常情况:
1.输入非法字符时:
2.输入的数据直接跟括号时:
3.左右括号没有同时出现时:
4.表达式没有写完时:
5.输入的除数为0时:
6.当输入多个小数点时:
七、实验运行情况分析
1.算法分析
程序利用两个栈,存放操作符和操作数,从输入流里读取字符。
将不同的操作符分类,规定优先数,利用前后操作符在栈的优先数不同,执行不同的操作符。
利用堆栈的“后进先出”(lastinfirstout)的特点实现中缀表达式的求值,效率较高并且比较容易完成代码的编写。
2.运行结果分析
(1)程序能够接受浮点数并正确表达式的值
(2)程序能够识别单目运算符
(3)当输入非法字符时,程序退出并提示表达式不符合要求
(4)程序可以识别除数为零的情况,并返回一个系统默认值
(5)程序能够识别当表达式不完整时的情况,并提示错误
(6)当输入一个含多个小数点的错误数字时,程序报错
(7)程序可以识别当括号不匹配时的错误
3.运行环境
该程序对运行环境要求较低,在单核计算机上也可以运行,内存最低要求56M。
在VisualC++6.0以及高于6.0的版本中基本可以运行.
参考文献:
[1]《C++大学教程》邱仲潘等译电子工业出版社2001.7
[2]《数据结构(用面向对象方法与c++描述)》殷人昆编著清华大学出版社1999.7
[3]《数据结构与算法(C++版)实验和课程设计教程》清华大学出版社