数据结构实验报告栈的应用.docx

上传人:b****5 文档编号:7466679 上传时间:2023-01-24 格式:DOCX 页数:15 大小:64.64KB
下载 相关 举报
数据结构实验报告栈的应用.docx_第1页
第1页 / 共15页
数据结构实验报告栈的应用.docx_第2页
第2页 / 共15页
数据结构实验报告栈的应用.docx_第3页
第3页 / 共15页
数据结构实验报告栈的应用.docx_第4页
第4页 / 共15页
数据结构实验报告栈的应用.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

数据结构实验报告栈的应用.docx

《数据结构实验报告栈的应用.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告栈的应用.docx(15页珍藏版)》请在冰豆网上搜索。

数据结构实验报告栈的应用.docx

数据结构实验报告栈的应用

实习报告

题目:

编制一个演示表达式求值的操作的程序

班级:

计算机(信息安全)姓名:

学号:

完成日期:

2009.3.27

∙需求分析

∙本演示程序中,元素限定为int整型和char型。

∙演示程序以用户和计算机的对话方式执行,即在计算机终端显示“提示信息“后,由用户在键盘上输入演示程序中规定的数值和运算符;相应的结果会显示其后。

∙程序执行命令包括:

∙根据用户给出的表达式进行运算2)输出结果

∙测试数据

用户输入:

1+2#结果:

3

用户输入:

12*(2+3)#结果:

60

用户输入:

13+5*(23+129)-187#结果:

586

∙概要设计

为实现上述程序功能,需要一个抽象数据类型:

1.栈的抽象数据类型定义为:

∙ADTStack{

∙数据对象:

D={ai∈ElemSet…}

∙数据关系:

R={…}

∙基本操作:

∙InitStack(&S);//构造空栈S

∙DestroyStack(&S);//销毁栈S

∙ClearStack(&S);//清空栈S

∙StackEmpty(S);//判断栈空

∙StackLength(S);//求栈长

∙GetTop(S,&e);//取栈顶

∙Push(&S,e);//入栈

∙Pop(&S,&e);//出栈

∙StackTraverse(S,visit());//遍历

∙}ADTStack

2.本程序包含四个模块:

1)主程序模块:

main()

{

初始化;

进入用户输入表达式阶段;

根据用户输入的表达式进行计算(利用while循环和栈)

输出运算结果

}

2)栈单元模块――实现栈抽象数据类型;

3)节点结构单元模块――定义有序表的节点结构。

各模块是之间关系如下:

∙详细设计

∙元素类型(此程序固定为int和char)结点类型

#defineSTACK_INT_SIZE100

#defineSTACKINCREAMENT10

TypedefcharSElemType1;

TypedefintSElemType2;

typedefstruct{

SElemType1*base;

SElemType1*top;

intstacksize;

}SqStack1;//节点类型(栈)

typedefstruct{

SElemType2*base;

SElemType2*top;

intstacksize;

}SqStack2;

2.栈的基本操作:

∙InitStack(&L);//构造空栈L

∙GetTop(L,&e);//取栈顶

∙Push(&L,e);//入栈

∙Pop(&L,&e);//出栈

 

栈部分操作伪码:

InitStack1(SqStack1&L){//初始化栈

L.base=(SElemType1*)malloc(STACK_INIT_SIZE*sizeof(SElemType1));

if(!

L.base)exit(OVERFLOW);

L.top=L.base;//置空栈

L.stacksize=SIZE_INIT_SIZE;}

InitStack2(SqStack12&L){//初始化栈

L.base=(SElemType2*)

malloc(STACK_INIT_SIZE*sizeof(SElemType2));

if(!

L.base)exit(OVERFLOW);

L.top=L.base;//置空栈

L.stacksize=SIZE_INIT_SIZE;}

GetTop1(SqStack1L){//取栈顶元素

if(L.top==L.base)

returnERROR;//空

return*(L.top-1);//栈顶指针不变

}

GetTop2(SqStack2L){//取栈顶元素

if(L.top==L.base)

returnERROR;//空

return*(L.top-1);//栈顶指针不变

}

 

Push1(SqStack1&L,SElemType1e){

if(L.top-L.base==L.stacksize)//栈满,需追加空间

L.base=(SElemType1*)realloc(L.base,(L.stacksize+STACKINCREMENT*sizeof(SElemType1));

if(!

L.base)exit(OVERFLOW);

L.top=L.base+L.stacksize;

L.stacksize+=STACKINCREMENT;}

*L.top++=e;//先赋值,再++

}

Push2(SqStack2&L,SElemType2e){

if(L.top-L.base==L.stacksize)//栈满,需追加空间

L.base=(SElemType2*)realloc(L.base,(L.stacksize+STACKINCREMENT*sizeof(SElemType2));

if(!

L.base)exit(OVERFLOW);

L.top=L.base+L.stacksize;

L.stacksize+=STACKINCREMENT;}

*L.top++=e;//先赋值,再++

}

 

Pop1(SqStack1&L,SElemType1&e){

if(L.top==L.base)returnERROR;//空

e=*--L.top;//先减,再取值

}

Pop2(SqStack2&L,SElemType2&e){

if(L.top==L.base)returnERROR;//空

e=*--L.top;//先减,再取值

}

∙主函数和其它函数的算法

(1)主函数

main()

{

SqStack1L1;

SqStack2L2;

charx;//存储被删的运算符栈的栈顶元素

charc;//存储每次用户从输入的元素

inta;//存储被删的数字栈的栈顶元素

intb;//存储被删的数字栈的栈顶元素

inte;//存储用户输入的字符是数字还是运算符的标记0-数字1-运算符(包括()#)

intk;//根据字符组合成多位数时用到的

intn;//根据字符组合成多位数时用到的

inti;

intnumber;//存储由用户输入的字符组成的多位数

intm;//记录用户输入的多位数的位数

intanswer;//结果

intcishu=1;//储存当前运算符被连续用到的次数(即首次读入某运算符,则其被用次数为1,当循环后未读取新字符而继续使用它是,其被用次数变为2)

charoldnum='N';//存储当前读入的运算符之前读入的字符,例如12*(5+4)#,“+”之前是数字”5”,而”#”之前是字符”)”而非数字

SuanFu();

InitStack1(&L1);

Push1(&L1,'#');

InitStack2(&L2);

printf("\n\nPleaseenterthenumberandtheoprater(end-#)");

printf("\n%c",GetTop1(&L1));

c=getchar();

m=0;

while(c!

='#'||GetTop1(&L1)!

='#'){

e=In(c);//判断读取的字符是否是运算符

if(e==0)//是数字

{

shuzi[m++]=c-'0';//将每次读取的数字字符转换成整型存入shuzi[]数组中

oldnum=c;//在读取下一字符前存储当前字符

c=getchar();

}

else{//是运算符

if(cishu==1&&In(oldnum)==0)//如果此运算符是刚被读取即第一次在循环中被用的且在读取其之前读取的字符是数字而不是运算符

{

k=1;

for(i=0;i

{

k=k*10;}

number=0;

根据用户入的数字字符组成多位数(整型)

for(i=0;i

n=shuzi[i]*k;

k=k/10;

number+=n;

}

Push2(&L2,number);

m=0;

}

switch(FuHao(GetTop1(&L1),c))//判断当前运算符与栈顶运算符的大小关系

{

case-1:

Push1(&L1,c);

oldnum=c;

c=getchar();

cishu=1;//读取一个新字符就改变其cishu

break;

case0:

Pop1(&L1,&x);

oldnum=c;

c=getchar();

cishu=1;//读取一个新字符就改变其cishu

break;

case1:

Pop1(&L1,&x);

Pop2(&L2,&b);

Pop2(&L2,&a);

cishu=2;//由于没有读取新字符即当前运算符会在下一次循环中再次用到,因此改变其cushu为2

Push2(&L2,Operate(a,x,b));

break;

}

}

}

Pop2(&L2,&answer);//读取最终结果

printf("\n%d",answer);

getch();

}

(2)构造存储运算符间大小关系的数组

voidSuanFu()

{

inti,j;

for(i=0;i<=3;i++){

for(j=0;j<=1;j++){

suanfu[i][j]=1;

}

}

for(i=0;i<=1;i++){

for(j=2;j<=3;j++){

suanfu[i][j]=-1;}

}

for(i=2;i<=3;i++){

for(j=2;j<=3;j++){

suanfu[i][j]=1;

}

}

 

for(i=4;i<=4;i++){

for(j=0;j<=3;j++){

suanfu[i][j]=-1;}

}

for(i=5;i<=5;i++){

for(j=0;j<=3;j++){

suanfu[i][j]=1;}

}

for(i=6;i<=6;i++){

for(j=0;j<=3;j++){

suanfu[i][j]=-1;}

}

 

for(i=0;i<=6;i++)

{suanfu[i][4]=-1;}

 

for(i=0;i<=5;i++)

{suanfu[i][5]=1;}

 

for(i=0;i<=6;i++)

{suanfu[i][6]=1;}

suanfu[4][6]=22;

suanfu[6][6]=0;

suanfu[5][4]=22;

suanfu[4][5]=0;

}

(3)构造判断啊a,b字符大小关系的函数

intFuHao(chara,charb)

{

if(a=='+')

{

if(b=='+')returnsuanfu[0][0];

if(b=='-')returnsuanfu[0][1];

if(b=='*')returnsuanfu[0][2];

if(b=='/')returnsuanfu[0][3];

if(b=='(')returnsuanfu[0][4];

if(b==')')returnsuanfu[0][5];

if(b=='#')returnsuanfu[0][6];

}

if(a=='-')

{

if(b=='+')returnsuanfu[1][0];

if(b=='-')returnsuanfu[1][1];

if(b=='*')returnsuanfu[1][2];

if(b=='/')returnsuanfu[1][3];

if(b=='(')returnsuanfu[1][4];

if(b==')')returnsuanfu[1][5];

if(b=='#')returnsuanfu[1][6];

}

if(a=='*')

{

if(b=='+')returnsuanfu[2][0];

if(b=='-')returnsuanfu[2][1];

if(b=='*')returnsuanfu[2][2];

if(b=='/')returnsuanfu[2][3];

if(b=='(')returnsuanfu[2][4];

if(b==')')returnsuanfu[2][5];

if(b=='#')returnsuanfu[2][6];

}

if(a=='/')

{

if(b=='+')returnsuanfu[3][0];

if(b=='-')returnsuanfu[3][1];

if(b=='*')returnsuanfu[3][2];

if(b=='/')returnsuanfu[3][3];

if(b=='(')returnsuanfu[3][4];

if(b==')')returnsuanfu[3][5];

if(b=='#')returnsuanfu[3][6];

}

if(a=='(')

{

if(b=='+')returnsuanfu[4][0];

if(b=='-')returnsuanfu[4][1];

if(b=='*')returnsuanfu[4][2];

if(b=='/')returnsuanfu[4][3];

if(b=='(')returnsuanfu[4][4];

if(b==')')returnsuanfu[4][5];

if(b=='#')returnsuanfu[4][6];

}

if(a==')')

{

if(b=='+')returnsuanfu[5][0];

if(b=='-')returnsuanfu[5][1];

if(b=='*')returnsuanfu[5][2];

if(b=='/')returnsuanfu[5][3];

if(b=='(')returnsuanfu[5][4];

if(b==')')returnsuanfu[5][5];

if(b=='#')returnsuanfu[5][6];

}

if(a=='#')

{

if(b=='+')returnsuanfu[6][0];

if(b=='-')returnsuanfu[6][1];

if(b=='*')returnsuanfu[6][2];

if(b=='/')returnsuanfu[6][3];

if(b=='(')returnsuanfu[6][4];

if(b==')')returnsuanfu[6][5];

if(b=='#')returnsuanfu[6][6];

}

}

(4)构造判断c是否为运算符的函数

intIn(charc)

{

if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')

return1;

elsereturn0;

}

(5)构造进行基本运算的函数

intOperate(inta,charc,intb)/*NOProblem*/

{

intd;

if(c=='+')

d=a+b;

if(c=='-')

d=a-b;

if(c=='*')

d=a*b;

if(c=='/')

d=a/b;

returnd;

}

(6)伪码变成c语言码示例(传入一个指向结构体的指针引用此函数时传入结构体的地址如:

&L1)

voidPush1(SqStack1*L1,SElemType1e)//进栈

{

if((*L1).top-(*L1).base>=(*L1).stacksize){(*L1).base=(SElemType1*)realloc((*L1).base,((*L1).stacksize+STACKINCREAMENT)*sizeof(SElemType1));

(*L1).top=(*L1).base+(*L1).stacksize;

(*L1).stacksize+=STACKINCREAMENT;

}

*((*L1).top++)=e;

}

voidPop1(SqStack1*L1,SElemType1*e)//出栈

{

*e=*((*L1).top-1);

(*L1).top--;

}

∙函数的调用关系:

Main

 

SuanFu

InitStack1InitStack2Push1Push2GetTop1GetTop2Pop1Pop2OperateIn

 

∙调试分析

∙对于InitStack1(SqStack1*L1)的引用,我开始写成了InitStack1(L1),没有传入L1的地址,出现错误,后来改为InitStack1(&L1),错误消失

∙对于Push1(SqStack1*L1,SElemType1e)的内部写法,我开始写的是

if(*L1.top-*L1.base>=*L1.stacksize)…

*L1.top=*L1.base+*L1.stacksize;之类的,出现了代码无效的错误

经改正:

if(*L1.top-(*L1).base>=(*L1).stacksize)

(*L1).top=(*L1).base+(*L1).stacksize;错误消失

3.开始一直出现警告没去管,结果输出的最终结果总是很大的数字,经过仔细的修改传入指针之类的程序,搞定了警告,输出结果就正确了,可见警告是不可忽视和笑看的!

4.开始对于SuanFu()开始构造的是字符型”>”“<”“=”,所以对于FuHao(chara,charb),返回的就是字符型,出现错误,因为不能return字符型,只能return整型,于是将”>”“<”“=”改为”1””-1””0”,错误消失

用户手册

∙本程序的运行怀镜为WindowsXp/2000操作系统,执行文件名为:

栈的应用(表达式求值).exe。

进入演示程序后即显示文本方式的用户界面:

 

∙进入主函数命令后,即提示键入您欲进行运算的表达式(以#作为表达式的结束标志),总的结束符为回车。

∙测试结果

执行命令Pleaseenterthenumberandtheoprater(end-#):

键入1+2#后,输出结果3

重新执行命令Pleaseenterthenumberandtheoprater(end-#):

键入1+2*3#后,输出结果7

重新执行命令Pleaseenterthenumberandtheoprater(end-#):

键入137*(24+6)-137*(15+15)#后,输出结果0

重新执行命令Pleaseenterthenumberandtheoprater(end-#):

键入128*(4+3*2)#后,输出结果1280

重新执行命令Pleaseenterthenumberandtheoprater(end-#):

键入12-160#后,输出结果-138

 

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

当前位置:首页 > 高等教育 > 理学

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

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