《带括号的表达式求值》课程设计报告.docx

上传人:b****6 文档编号:6954631 上传时间:2023-01-13 格式:DOCX 页数:23 大小:103.05KB
下载 相关 举报
《带括号的表达式求值》课程设计报告.docx_第1页
第1页 / 共23页
《带括号的表达式求值》课程设计报告.docx_第2页
第2页 / 共23页
《带括号的表达式求值》课程设计报告.docx_第3页
第3页 / 共23页
《带括号的表达式求值》课程设计报告.docx_第4页
第4页 / 共23页
《带括号的表达式求值》课程设计报告.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

《带括号的表达式求值》课程设计报告.docx

《《带括号的表达式求值》课程设计报告.docx》由会员分享,可在线阅读,更多相关《《带括号的表达式求值》课程设计报告.docx(23页珍藏版)》请在冰豆网上搜索。

《带括号的表达式求值》课程设计报告.docx

《带括号的表达式求值》课程设计报告

《数据结构与算法分析》课程设计报告

 

课题名称:

带括号的算术表达式求值

 

课题负责人名(学号):

0743111298

同组成员名单(角色):

戴维

指导教师:

评阅成绩:

评阅意见:

提交报告时间:

200年月日

带括号的算术表达式求值

软件工程专业

 

学生戴维指导老师朱宏

 

一、实验一:

带括号的算术表达式求值

二、实验的目的和要求:

1.采用算符优先数算法,能正确求值表达式;

2.熟练掌握栈的应用;

3.熟练掌握计算机系统的基本操作方法,了解如何编辑、编译、链接和运行一个C++程序;

4.上机调试程序,掌握查错、排错使程序能正确运行。

三、实验的环境:

1.硬件环境:

Intel(R)Celeron(R)MCPU

520@1.60GHz

1.60GHz,0.99Gb内存

2.软件环环境:

操作系统:

MicrosoftWindowsXP

Professinal版本2002

编译系统版本:

MicroSoftVisualC++6.0

包括操作系统,编译系统的版本的特点,编辑软件特点等。

四、算法描述:

对于带有括号的算术表达式有以下的运算法则:

1.先乘方,再乘除,最后加减。

2.同级运算从左到右。

3.先括号内,再括号外。

而运算符号的优先级别如下表所示:

运算符

=

()

+-

*/%

^

优先级

1

2

3

4

5

具体实现如下:

1.先建立两个堆栈,一个是操作符堆栈,一个为操作数堆栈。

并且将这两个堆栈先清空,然后在操作符号堆栈当中放入一个“=”,以便在后面方便判断表达式是否结束。

2.从输入流当中读取一个字符,循环执行下面的操作:

去出操作符号堆栈的栈顶元素,如果栈顶元素是不是“=”并且如果当前的字符也是“=”的时候,那么表示表达式已经结束了,当前操作数堆栈的栈顶元素就是表达式的值。

如果当前字符不是操作符,就将当前字符放回到输入流当中,读取操作数,并且将操作数加入到操作数堆栈当中,继续读入下一个字符。

如果当前字符是操作符就进行下面的操作:

.如果当前字符不是“+”或者“-”,则在当前字符前面加一个“0”放入到操作数栈当中。

如果当前字符和操作符的栈顶元素不匹配,例如当前字符是“(”,而栈顶字符“)”,显示错误信息。

如果操作符栈的栈顶元素是“(”并且当前字符是“)”,则从操作符栈当中取出,去掉括号,然后继续读入下面的字符。

如果当前字符是“(”,或者操作符栈顶元素的优先级别比当前字符低,则将当前字符放入到操作符栈当中。

继续读入下一个字符。

如果操作符栈顶元素的优先级别等于或者大于当前字符的优先级别,那么就取出操作数栈的RIGHT和LEFT元素,从操作符栈当中取出OP,然后进行操作(LEFT)OP(RIGHT),结果进入到操作数栈当中.

五、源程序清单:

Calculator.h:

template

classCalculator

{

private:

Stackopnd;//建立一个操作数的栈

Stackoptr;//建立一个操作符的栈

boolGetTwoOperands(double&left,double&right);

//从操作数栈当中取出最上面的两个数字

boolDoOperator(charop);

//runthefunction"leftopright"

boolIsOperator(charch);

//判断传入的字符是不是一个操作符

voidGetChar(char&ch);

//从输入流当中读入一个字符

intisp(charop);//堆栈外优先数

inticp(charop);//堆栈内优先数

public:

voidRun();//运行函数

};

template

voidCalculator:

:

Run()

{

optr.clear();//将操作符栈的所有元素清空

opnd.clear();//将操作数栈的所有元素清空

optr.push('=');//先在操作符栈中传入一个‘=’号,为了能够更好的判断运算是否已经

结束

//当从外面的读入的字符是‘=’并且栈顶符号也是‘=’时,运算结束

charch;//临时的一个字符

charpriorChar;//前一个字符

charoptrTop;//操作符栈的栈顶元素

Data_elementoperand;//需要被操作的操作数

charop='0';//定义一个操作数为‘0’,便于操作小数的运算

GetChar(ch);//得到一个字符

optr.top(optrTop);//得到操作符栈的栈顶元素

if(optr.top(optrTop)==underflow)

//如果操作符号栈为空,抛出错误信息

{

cout<<"表达式有错!

"<

return;

}

while(optrTop!

='='||ch!

='=')

//通过判断当前的字符和栈顶的字符其中一个不为“=”的时候,

//表示现在运算还没有结束,所以进行下面的操作

{

if(isdigit(ch)||ch=='.')

//如果当先的字符是一个数字或者当前字符是小数点,那么把该字符放回到

输入流当中,

//再把该操作数读入,并且放到操作数栈当中去,把前一个字符赋为0,然后

再继续读入字符

{

cin.putback(ch);

cin>>operand;

opnd.push(operand);

priorChar='0';

GetChar(ch);

}

elseif(!

IsOperator(ch))

//除了数字以外应该只有操作符,现在进行判断,如果不是数字,不是小数

点,

//也不是操作符号,说明输入有错误,打印错误消息,再不断的读入字符,

直到读到表达式结束

{

cout<<"表达式中出现非法字符!

"<

while(cin>>ch,ch!

='=');

return;

}

else

{

if((priorChar=='='||priorChar=='(')&&(ch=='+'||ch=='-'))opnd.push

(0);

if(isp(optrTop)

//如果操作符栈顶元素的优先级别小于当前操作符号的优先级别就

把当前的

//字符放到操作符栈当中,将当前字符赋值给前一个字符,再读入下一

个字符

{

optr.push(ch);

priorChar=ch;

GetChar(ch);

}

elseif(isp(optrTop)>icp(ch))

//如果操作符栈顶元素的优先级别大于当前操作符号,

//删除操作符栈顶元素,在判断OP是不是操作符号,如果不是就返回

{

optr.top(op);optr.pop();

if(!

DoOperator(op))return;

}

elseif(isp(optrTop)==icp(ch)&&ch==')')

//如果栈内操作符和栈外操作符的优先级别一样的,并且当前的字

符为等号的时候

{

optr.pop();

priorChar=')';

GetChar(ch);

};

}

if(optr.top(optrTop)==underflow)

//如果操作符栈为空的话,输出错误消息

{

cout<<"表达式有错!

"<

return;

};

}

if(opnd.top(operand)==underflow||optr.pop()==underflow)

//如果操作数字栈为空或者是操作符号在删除了栈顶元素厚为空,输出错误信息

{

cout<<"表达式有错!

"<

return;

}

else

//删除操作数栈的栈顶元素,如果再删除操作符栈栈顶元素成功删除或者能够成功删除

//操作数栈的栈顶元素,输出错误信息

{

opnd.pop();

if(opnd.pop()==success||optr.pop()==success)

{

cout<<"表达式有错!

"<

return;

}

cout<

return;

}

};

template

intCalculator:

:

isp(charop)

//栈外操作符的优先级判断

{

intresult;

switch(op)

{

case'=':

result=0;

break;

case'(':

result=1;

break;

case'^':

result=7;

break;

case'*':

case'/':

case'%':

result=5;

break;

case'+':

case'-':

result=3;

break;

case')':

result=8;

}

returnresult;

};

template

//操作符栈内优先级的判断

intCalculator:

:

icp(charop)

{

intresult;

switch(op)

{

case'=':

result=0;

break;

case'(':

result=8;

break;

case'^':

result=6;

break;

case'*':

case'/':

case'%':

result=4;

break;

case'+':

case'-':

result=2;

break;

case')':

result=1;

}

returnresult;

};

template

boolCalculator:

:

GetTwoOperands(double&x,double&y)

//从操作数栈当中得到两个数字,如果操作数字栈或者操作符栈的元素少于两个的时候输出错误信息

{

if(opnd.empty())

{

cout<<"表达式有错!

"<

returnfalse;

}

opnd.top(y);opnd.pop();

if(opnd.empty())

{

cout<<"表达式有错!

"<

returnfalse;

}

opnd.top(x);opnd.pop();

returntrue;

};

template

boolCalculator:

:

DoOperator(charop)

//判断符号,进行相应的操作

{

Data_elementx,y;

boolresult=GetTwoOperands(x,y);

if(result==true)

{

switch(op)

{

case'+':

opnd.push(x+y);

break;

case'-':

opnd.push(x-y);

break;

case'*':

opnd.push(x*y);

break;

case'/':

if(y==0)

{

cout<<"除数为零!

"<

returnfalse;

}

opnd.push(x/y);

break;

case'%':

if((long)y==0)

{

cout<<"除数为零!

"<

returnfalse;

}

opnd.push((long)x%(long)y);

break;

case'^':

opnd.push(pow(x,y));

}

returntrue;

}

elsereturnfalse;

};

template

voidCalculator:

:

GetChar(char&ch)

//从输入流当中读入字符

{

cin>>ch;

while(ch==''||ch=='\n')

cin>>ch;

};

template

boolCalculator:

:

IsOperator(charch)

//判断输入的字符是不是操作符

{

if(ch=='='||ch=='('||ch=='^'||ch=='*'||

ch=='/'||ch=='%'||ch=='+'||ch=='-'||ch==')')

returntrue;

else

returnfalse;

};

LK_STACK.h:

template

structNode{

Node_entryentry;//定义一个结点元素

Node*next;//定义一个结点指针

Node();//无参数构造函数

Node(Node_entryitem,Node*add_on=NULL);//含参构造函数

};

template

classStack{

public:

Stack();//无参构造函数

boolempty()const;//判断堆栈是不是为空

Error_codepush(constStack_entry&item);//往堆栈当中传入元素

Error_codepop();//删除堆栈的栈顶元素

Error_codetop(Stack_entry&item)const;//得到堆栈的栈顶元素

voidclear();//清空堆栈的所有元素

~Stack();//析构函数

Stack(constStack&original);//有参数构造函数

voidoperator=(constStack&original);//操作符重载

protected:

Node*top_node;//定义一个指针

};

template

Node:

:

Node()//构造函数

{

next=NULL;

}

template

Node:

:

Node(Node_entryitem,Node*add_on)

//含参数构造函数

{

entry=item;

next=add_on;

}

template

Stack:

:

Stack()

//堆栈的构造函数

{

top_node=NULL;

}

template

boolStack:

:

empty()const

//判断堆栈是不是为空

{

if(top_node==NULL)

returntrue;

else

returnfalse;

}

template

Error_codeStack:

:

push(constStack_entry&item)

//往堆栈中添加元素

{

Node*new_top=newNode(item,top_node);

if(new_top==NULL)returnoverflow;

top_node=new_top;

returnsuccess;

}

template

Error_codeStack:

:

pop()

//删除堆栈的栈顶元素

{

Node*old_top=top_node;

if(top_node==NULL)returnunderflow;

top_node=old_top->next;

deleteold_top;

returnsuccess;

}

template

Error_codeStack:

:

top(Stack_entry&item)const

//得到堆栈的栈顶元素

{

Error_coderesult;

if(empty())

returnunderflow;

else{

item=top_node->entry;

returnsuccess;

}

}

template

voidStack:

:

clear()

//清空整个堆栈

{

while(!

empty())

pop();

}

 

template

Stack:

:

~Stack()

//析构函数

{

clear();

}

Utility.h:

#include//standardstringoperations

#include//standardiostreamoperations

#include//numericlimits

#include//mathematicalfunctions

#include//fileinputandoutput

#include//characterclassification

#include//dateandtimefunction

#include//coninputandoutput

enumError_code{success,fail,underflow,overflow};

//enumbool{false,true};

Calculator.cpp:

#include"Utility.h"

#include"LK_STACK.H"

#include"Calculator.h"

voidmain()

{

Calculators;

chariscontinue='Y';

while(iscontinue=='Y')

{

cout<<"输入表达式(以等号“=”结束):

"<

s.Run();

cout<<"是否继续(Y/N)?

";

cin>>iscontinue;

iscontinue=toupper(iscontinue);

}

}

六、运行结果:

1.一般的整数操作:

3+4*5/2=13

2.小数的计算:

4.25*1+3.25/5=4.9

3.乘方操作:

4^4=256

4.取模运算:

7%3=1

5.负数运算:

(-5)*6/2=15

6.分母为零的检验:

7.一次程序结束后继续下一次:

8.一次程序结束后退出程序:

七、实验运行情况分析(包括算法、运行结果、运行环境等问题的讨论)。

(一)算法分析:

对于带有括号的算术表达式有以下的运算法则:

1.先乘方,再乘除,最后加减。

2.同级运算从左到右。

3.先括号内,再括号外。

而运算符号的优先级别如下表所示:

运算符

=

()

+-

*/%

^

优先级

1

2

3

4

5

具体实现如下:

1.先建立两个堆栈,一个是操作符堆栈,一个为操作数堆栈。

并且将这两个堆栈先清空,然后在操作符号堆栈当中放入一个“=”,以便在后面方便判断表达式是否结束。

2.从输入流当中读取一个字符,循环执行下面的操作:

去出操作符号堆栈的栈顶元素,如果栈顶元素是不是“=”并且如果当前的字符也是“=”的时候,那么表示表达式已经结束了,当前操作数堆栈的栈顶元素就是表达式的值。

如果当前字符不是操作符,就将当前字符放回到输入流当中,读取操作数,并且将操作数加入到操作数堆栈当中,继续读入下一个字符。

如果当前字符是操作符就进行下面的操作:

.如果当前字符不是“+”或者“-”,则在当前字符前面加一个“0”放入到操作数栈当中。

如果当前字符和操作符的栈顶元素不匹配,例如当前字符是“(”,而栈顶字符“)”,显示错误信息。

如果操作符栈的栈顶元素是“(”并且当前字符是“)”,则从操作符栈当中取出,去掉括号,然后继续读入下面的字符。

如果当前字符是“(”,或者操作符栈顶元素的优先级别比当前字符低,则将当前字符放入到操作符栈当中。

继续读入下一个字符。

如果操作符栈顶元素的优先级别等于或者大于当前字符的优先级别,那么就取出操作数栈的RIGHT和LEFT元素,从操作符栈当中取出OP,然后进行操作(LEF

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

当前位置:首页 > 幼儿教育 > 幼儿读物

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

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