算是表达式栈实验报告.docx

上传人:b****4 文档编号:3773105 上传时间:2022-11-25 格式:DOCX 页数:16 大小:39.51KB
下载 相关 举报
算是表达式栈实验报告.docx_第1页
第1页 / 共16页
算是表达式栈实验报告.docx_第2页
第2页 / 共16页
算是表达式栈实验报告.docx_第3页
第3页 / 共16页
算是表达式栈实验报告.docx_第4页
第4页 / 共16页
算是表达式栈实验报告.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

算是表达式栈实验报告.docx

《算是表达式栈实验报告.docx》由会员分享,可在线阅读,更多相关《算是表达式栈实验报告.docx(16页珍藏版)》请在冰豆网上搜索。

算是表达式栈实验报告.docx

算是表达式栈实验报告

 

中南大学

 

《数据结构与算法》课程实验

实验报告

 

题目线性表的操作

学生姓名张悦

学生学号3901090516

专业班级软件工程0905班

实验二栈的基本操作

一、实验目的

熟练掌握栈的基本操作:

初始化栈、判栈为空、出栈、入栈等运算。

理解栈在数据处理中扮演的角色,运用栈结构实现具体的应用。

二、实验内容

栈是数据结构中一个非常重要的结构。

表达式计算是掌握程序设计语言的重要部分之一,也是栈的应用的一个典型例子。

本次实验的主要内容是利用栈的基本操作,设计一个程序,实现用算符优先法对算术表达式求值的过程。

对本设计系统实现+、-、*、/、%和乘方(^)运算。

符合要求,同时提高自己的编程能力。

实现算术表达式求值。

选作内容:

提供对小数点的支持,允许输入的表达式中出现多位数字和小数点。

三、实验要求

1.认真阅读和掌握本实验的算法。

2.上机将本算法实现。

3.在程序的编写中尽量与专业的编程规范靠拢,系统代码采用结构化的编程方式,力求设计代码以及注释等规范,

4.保存和打印出程序的运行结果,并结合程序进行分析。

一.需求分析

本程序用于计算“+”、“-”、“*”、“\”、“^”、“()”的简单计算器,对简单的计算式子进行计算,并输出运算结果。

1.输入的形式和输入值的范围:

整数类型的实数(float),并以“#”对每个式子结尾;

2.输出的形式:

算式的最后结果;

3.程序所能达到的功能:

计算出所输入运算式子的结果;

4.测试数据:

①正确输入:

(3+4)*5#

输出结果:

35

②错误输入:

没有以“#”结尾、除数为0、输入了除“+”、“-”、“*”、“\”、“^”、“()”意外的运算符、括号的左右不匹配、数据溢出等。

输出结果:

“Operatorerror!

”、“Dividezero!

”、“Inputerror,Retry!

”、“Outofspace!

二.概要设计

栈的储存结构:

此方法中用到的抽象数据类型为结构体:

structSTACK1{//此为操作符的栈;

charsta[MAX];

inttop;

};

typedefstructSTACK1stack1;

structSTACK2{//此为运算数的栈;

floatsta[MAX];

inttop;

};

typedefstructSTACK2stack2;

主程序中提示输入所需要计算的运算公式,调用check_ch函数检查输入是否错误,然后调用operate函数计算所输入算式的计算所得结果;其中在operate函数中还调用了pop、push、Output等函数对所输入的运算公式进行计算。

最后用在主函数中直接输出经过operate函数计算后的程序结果。

三.详细设计

定义的栈的结构体:

structSTACK1{//储存运算符的栈

charsta[MAX];//定义存入运算符为char类型数据

inttop;

};

structSTACK2{//储存数字的栈

floatsta[MAX];//定义存入数字为float类型数据

inttop;

};

typedefstructSTACK1stack1;

typedefstructSTACK2stack2;

所用主要函数:

intcheck_ch(charch[MAX]){//查看表达式括号是否匹配函数

inti=0;

chartch;

stack1*s;

s=newstack1;

s->top=0;

while(ch[i]!

='#'){

switch(ch[i]){

case'(':

push(ch[i],s);break;

case')':

if(!

IsEmpty(s)){

tch=pop(s);

if(tch=='(')break;

elsereturn0;

}

else{

return0;

}

}

i++;

}

if(IsEmpty(s))

return1;

else

return0;

}

floatoperate(stack1*base,stack2*operand,charch[MAX]){//计算所给表达式的值

chartch;

inti=0;

push('#',base);//在栈低先压入"#"

while(ch[i]!

=NULL){

if(check(ch[i])){//对于运算表达式中的字符进行判断

floatNUM,num;

NUM=0;

while(check(ch[i])){

num=ch[i]-'0';

NUM=NUM*10+num;

i++;

}

push(NUM,operand);

}

else{

if(!

IsEmpty(base)){

if(ch[i]==')'){//遇到"("时的计算

tch=pop(base);

while(tch!

='('){

Output(tch,base,operand);

tch=pop(base);

}

}

else{

tch=base->sta[base->top];

while(Osp(ch[i])

tch=pop(base);

Output(tch,base,operand);

tch=base->sta[base->top];

}

push(ch[i],base);

}

}

else{

push(ch[i],base);

}

i++;

}

}

tch=pop(base);

while(tch!

='#'){//把栈中剩余的运算符弹出进行计算

Output(tch,base,operand);

tch=pop(base);

}

returnpop(operand);//弹出栈中最后的数,即为运算式子的最后结果

}

intOutput(charch,stack1*base,stack2*operand){//弹出运算符时进行两数的运算

floatn1,n2,num;

n1=pop(operand);

n2=pop(operand);

num=analyse(n1,n2,ch);

push(num,operand);

return0;

}

主函数:

intmain(){

intflag;

while(flag){

charch[MAX],c;

stack1*base;

stack2*operand;

base=newstack1;

operand=newstack2;

floatnum;

if(base==NULL){

cout<<"Outofspace!

"<

return-1;

}

if(operand==NULL){

cout<<"Outofspace!

"<

return-1;

}

base->top=-1;

operand->top=-1;

cout<<"PleaseentertheExpressions,andendwith‘#’:

"<

cin>>ch;

if(!

check_ch(ch)){

cout<<"puterror,Retry!

"<

continue;

}

num=operate(base,operand,ch);

cout<<"Theansweris"<

cout<<"Doyouwanttocontinue?

(y/n):

";

cin>>c;

if(c=='y'||c=='Y')//实现多次输入

flag=1;

else

flag=0;

deletebase;

deleteoperand;

}

return0;

}

函数和过程的调用关系图:

四.调试分析

在最一开始的时候,觉得栈是一个很神秘很抽象的东西,听老师讲课也觉得似懂非懂的,觉得理论上好像懂了,但遇到实际操作时,又开始糊涂了。

直到要开始做实验,对于栈的程序代码的编写才开始有了比较清晰的轮廓。

指针这方面我不太在行,所以我选择了用数组来进行栈的数据储存。

我觉得数和运算符应该分开,分别为两个栈,所以我用两个结构体分别定义了一个储存字符和数字。

为了能判断输入的数是否结束,我要求程序使用者在输入完算式后以“#”做结尾。

考虑到有些人会不注意输入的格式,或者是括号没有匹配等,借鉴了老师的程序,我用check_ch函数来判断输入的算式是否符合要求,如果不符合要求,则重新输入。

输入结束后,我就直接用了一个笼统的函数operate来对该算式来进行运算。

我对输入的字符串一个一个字符的进行操作。

当遇到数字时,用push函数压入数字栈内;当遇到符号时,分类讨论。

当符号为“)”时,开始放出符号栈中的栈顶符号,并进行运算,知道遇到符号“)”停止。

当遇到的是普通的符号时,比较符号栈的栈顶符号与该符号的优先级大小,优先级大的先进行运算。

运算是指在栈中弹出最后两个数与当前运算符进行运算,将得到的结果压入数字栈中。

当遇到“#”时,运算结束,弹出数字栈中最后的数,即为最终答案。

在实验过程中,一开始的程序是有错误的,主要是没有考虑到符号栈中当除去括号外多余的符号,而且“i++”这一句语句放错了位置,导致程序的结果永远是我输入的最后一位数字。

经过反复修改后,我的程序终于可以正常的运行了。

感谢老师提供的程序,让我解决了许多程序中无法正常运行的部分,并且我知道了如何输入多位数,让程序可以进行多位数的运算。

五.用户使用说明

运行程序后,会出现提示:

PleaseentertheExpressions,andendwith‘#’:

(输入运算式子,并以“#”结尾,按回车;例如输入:

(3+4)*5)

程序运行后,屏幕上会显示出:

Theansweris35.

Doyouwanttocontinue?

(y/n):

(输入Y或y,程序将继续进行计算,否则退出程序)

六.测试结果

七.附录

#include

usingnamespacestd;

constMAX=50;

structSTACK1{//储存运算符的栈

charsta[MAX];

inttop;

};

structSTACK2{//储存数字的栈

floatsta[MAX];

inttop;

};

typedefstructSTACK1stack1;

typedefstructSTACK2stack2;

floatoperate(stack1*base,stack2*operand,charch[MAX]);

intcheck(charch);

intIsp(charch);

intOsp(charch);

charpop(stack1*base);

floatpop(stack2*operand);

floatanalyse(floatn,floatm,charch);

floatpower(floatn,floatm);

intpush(floatnum,stack2*operand);

intpush(charch,stack1*base);

intIsEmpty(stack1*base);

intOutput(charch,stack1*base,stack2*operand);

intcheck_ch(charch[MAX]);

intmain(){

intflag;

while(flag){

charch[MAX],c;

stack1*base;

stack2*operand;

base=newstack1;

operand=newstack2;

floatnum;

if(base==NULL){

cout<<"Outofspace!

"<

return-1;

}

if(operand==NULL){

cout<<"Outofspace!

"<

return-1;

}

base->top=-1;

operand->top=-1;

cout<<"PleaseentertheExpressions,andendwith'#':

"<

cin>>ch;

if(!

check_ch(ch)){

cout<<"puterror,Retry!

"<

continue;

}

num=operate(base,operand,ch);

cout<<"Theansweris"<

cout<<"Doyouwanttocontinue?

(y/n):

";

cin>>c;

if(c=='y'||c=='Y')//实现多次输入

flag=1;

else

flag=0;

deletebase;

deleteoperand;

}

return0;

}

intcheck_ch(charch[MAX]){//查看表达式括号是否匹配函数

inti=0;

chartch;

stack1*s;

s=newstack1;

s->top=0;

while(ch[i]!

='#'){

switch(ch[i]){

case'(':

push(ch[i],s);break;

case')':

if(!

IsEmpty(s)){

tch=pop(s);

if(tch=='(')break;

elsereturn0;

}

else{

return0;

}

}

i++;

}

if(IsEmpty(s))

return1;

else

return0;

}

floatoperate(stack1*base,stack2*operand,charch[MAX]){//计算所给表达式的值

chartch;

inti=0;

push('#',base);//在栈低先压入"#"

while(ch[i]!

=NULL){

if(check(ch[i])){//对于运算表达式中的字符进行判断

floatNUM,num;

NUM=0;

while(check(ch[i])){

num=ch[i]-'0';

NUM=NUM*10+num;

i++;

}

push(NUM,operand);

}

else{

if(!

IsEmpty(base)){

if(ch[i]==')'){//遇到"("时的计算

tch=pop(base);

while(tch!

='('){

Output(tch,base,operand);

tch=pop(base);

}

}

else{

tch=base->sta[base->top];

while(Osp(ch[i])

tch=pop(base);

Output(tch,base,operand);

tch=base->sta[base->top];

}

push(ch[i],base);

}

}

else{

push(ch[i],base);

}

i++;

}

}

tch=pop(base);

while(tch!

='#'){//把栈中剩余的运算符弹出进行计算

Output(tch,base,operand);

tch=pop(base);

}

returnpop(operand);//弹出栈中最后的数,即为运算式子的最后结果

}

intOutput(charch,stack1*base,stack2*operand){//弹出运算符时进行两数的运算

floatn1,n2,num;

n1=pop(operand);

n2=pop(operand);

num=analyse(n1,n2,ch);

push(num,operand);

return0;

}

intIsEmpty(stack1*base){//判断栈是否为空

if(base->top==0)

return1;

else

return0;

}

intcheck(charch){//判断读入的字符是否为数字

if(ch<'0'||ch>'9')

return0;

else

return1;

}

intpush(floatnum,stack2*operand){//压入栈的操作

operand->top++;

if(operand->top>MAX){

cout<<"Outofspace!

"<

return-1;

}

operand->sta[operand->top]=num;

return0;

}

intpush(charch,stack1*base){

base->top++;

if(base->top>MAX){

cout<<"Outofspace!

"<

return-1;

}

base->sta[base->top]=ch;

return0;

}

charpop(stack1*base){//弹出栈的操作

chartch;

tch=base->sta[base->top];

base->top--;

returntch;

}

floatpop(stack2*operand){

floattnum;

tnum=operand->sta[operand->top];

operand->top--;

returntnum;

}

intIsp(charch){//运算符优先级的判断

switch(ch){

case'#':

return0;break;

case'(':

return1;break;

case'+':

return3;break;

case'-':

return3;break;

case'*':

return5;break;

case'/':

return5;break;

case'^':

return7;break;

case')':

return8;break;

}

}

intOsp(charch){

switch(ch){

case'#':

return0;break;

case'(':

return8;break;

case'+':

return2;break;

case'-':

return2;break;

case'*':

return4;break;

case'/':

return4;break;

case'^':

return6;break;

case')':

return1;break;

}

}

floatanalyse(floatn,floatm,charch){

switch(ch){

case'+':

return(n+m);break;

case'-':

return(m-n);break;

case'*':

return(n*m);break;

case'^':

return(power(m,n));break;

case'/':

if(n==0){

cout<<"Dividezero!

"<

exit(-1);

}

else{

returnm/n;

break;

}

default:

cout<<"Operatorerror!

"<

exit(-1);

}

}

floatpower(floatn,floatm){

floatsum=1;

for(inti=0;i

sum=sum*n;

}

returnsum;

}

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

当前位置:首页 > 考试认证 > 交规考试

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

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