北理工数据结构实验报告.docx

上传人:b****1 文档编号:569476 上传时间:2023-04-29 格式:DOCX 页数:19 大小:39.52KB
下载 相关 举报
北理工数据结构实验报告.docx_第1页
第1页 / 共19页
北理工数据结构实验报告.docx_第2页
第2页 / 共19页
北理工数据结构实验报告.docx_第3页
第3页 / 共19页
北理工数据结构实验报告.docx_第4页
第4页 / 共19页
北理工数据结构实验报告.docx_第5页
第5页 / 共19页
北理工数据结构实验报告.docx_第6页
第6页 / 共19页
北理工数据结构实验报告.docx_第7页
第7页 / 共19页
北理工数据结构实验报告.docx_第8页
第8页 / 共19页
北理工数据结构实验报告.docx_第9页
第9页 / 共19页
北理工数据结构实验报告.docx_第10页
第10页 / 共19页
北理工数据结构实验报告.docx_第11页
第11页 / 共19页
北理工数据结构实验报告.docx_第12页
第12页 / 共19页
北理工数据结构实验报告.docx_第13页
第13页 / 共19页
北理工数据结构实验报告.docx_第14页
第14页 / 共19页
北理工数据结构实验报告.docx_第15页
第15页 / 共19页
北理工数据结构实验报告.docx_第16页
第16页 / 共19页
北理工数据结构实验报告.docx_第17页
第17页 / 共19页
北理工数据结构实验报告.docx_第18页
第18页 / 共19页
北理工数据结构实验报告.docx_第19页
第19页 / 共19页
亲,该文档总共19页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

北理工数据结构实验报告.docx

《北理工数据结构实验报告.docx》由会员分享,可在线阅读,更多相关《北理工数据结构实验报告.docx(19页珍藏版)》请在冰点文库上搜索。

北理工数据结构实验报告.docx

北理工数据结构实验报告

 

《数据结构与算法设计》

实验报告

——实验二

 

学院:

自动化学院

班级:

____

学号:

__

姓名:

_____

 

一、实验目的

1、熟悉VC环境,学习使用C语言实现栈的存储结构。

2、通过编程、上机调试,进一步理解栈的基本概念。

3、锻炼动手编程,独立思考的能力。

二、实验内容

实现简单计算器的功能,请按照四则运算加、减、乘、除、幂(^)和括号的优先关系和惯例,编写计算器程序。

要求支持运算符:

+、-、*、/、%、()和=:

①从键盘输入一个完整的表达式,以回车作为表达式输入结束的标志;

②输入表达式中的数值均为大于等于零的整数,如果中间计算过程中出现小数也只取整进行计算。

例如,输入:

4+2*5=输出:

14

输入:

(4+2)*(2-10)=输出:

-48

三、程序设计

1、概要设计

为实现上述程序功能,应使用两个栈,分别寄存操作数与运算符。

为此,需要栈的抽象数据结构。

(1)、栈的抽象数据类型定义为:

ADTStack{

数据对象:

D=

数据关系:

R1=

约定

端为栈顶,

端为栈底。

基本操作:

InitStack(&S)

操作结果:

创建一个空栈S。

GetTop(S,&e)

初始条件:

栈S已存在且非空。

操作结果:

用e返回S的栈顶元素。

Push(&S,e)

初始条件:

栈S已存在。

操作结果:

插入元素e为新的栈顶元素。

Pop(&S,&e)

初始条件:

栈S已存在且非空。

操作结果:

删除S的栈顶元素,并用e返回其值。

In(m,a[])

操作结果:

若m是运算符,返回TRUE。

Precede(m,n)

初始条件:

m,n为运算符。

操作结果:

若m优先级大于n,返回>,反之亦然。

Operation(a,theta,b)

初始条件:

a,b为整数,theta为运算符。

操作结果:

返回a与b运算的结果。

EvaluateExpression(p[])

初始条件:

输入合法的表达式。

操作结果:

返回表达式的值。

}ADTStack

(2)、宏定义

#defineSTACK_INIT_SIZE100

#defineSTACKINCREMENT10

#defineOVERFLOW-2

#defineOK1

#defineERROR0

#defineTRUE1

#defineFALSE0

(3)、主程序流程

首先定义char型数组,将输入的表达式存入。

随后调用EvaluateExpression(expression)函数计算结果,最后输出在屏幕上。

(4)、模块调用关系:

由主函数模块调用输入模块与求值模块。

求值模块调用表达式转化模块与表达式求职模块,计算并返回表达式的值。

最后主程序调用输出模块输出结果。

(5)、流程图

 

开始

输入表达式

charc=表达式首字符

c!

='='||GetTop1(OPTR)!

='='

!

In(c,OP)

c存入数组;c=*(++ex);

In(c,OP)

数组中的数压入栈内;指针指向数组首元素

case'<':

符号进栈c=*(++ex);

case'=':

符号出栈c=*(++ex);

case'>':

操作数栈前2个数运算

returnGetTop2(OPND)

输出result

结束

 

2、详细设计

(1)、数据类型设计

typedefstruct{

char*base;

char*top;

intstacksize;

}SqStack1;//定义运算符栈数据类型

typedefstruct{

int*base;

int*top;

intstacksize;

}SqStack2;//定义操作数栈数据类型

SqStack1OPTR;//声明运算符栈

SqStack2OPND;//声明操作数栈

(2)、操作算法设计

StatusInitStack1(SqStack1&S){

//构造运算符栈

S.base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));

//申请空间

if(!

S.base)exit(OVERFLOW);//存储分配失败

S.top=S.base;

S.stacksize=STACK_INIT_SIZE;

returnOK;

}//InitStack1

StatusInitStack2(SqStack2&S){

//构造操作数栈

S.base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));

//申请空间

if(!

S.base)exit(OVERFLOW);//存储分配失败

S.top=S.base;

S.stacksize=STACK_INIT_SIZE;

returnOK;

}//InitStack2

charGetTop1(SqStack1S){

//取得运算符栈的栈顶元素

chare;

if(S.top==S.base)returnERROR;//栈空

e=*(S.top-1);

returne;

}//GetTop1

intGetTop2(SqStack2S){

//取得操作数栈的栈顶元素

inte;

if(S.top==S.base)returnERROR;//栈空

e=*(S.top-1);

returne;

}//GetTop2

StatusPush1(SqStack1&S,chare){

//插入元素e为运算符栈的栈顶元素

if(S.top-S.base>=S.stacksize){//栈满,追加存储空间

S.base=(char*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));

if(!

S.base)exit(OVERFLOW);//存储分配失败

S.top=S.base+S.stacksize;

S.stacksize+=STACKINCREMENT;

}

*S.top++=e;

returnOK;

}//Push1

StatusPush2(SqStack2&S,inte){

//插入元素e为操作数栈的栈顶元素

if(S.top-S.base>=S.stacksize){//栈满,追加存储空间

S.base=(int*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(int));

if(!

S.base)exit(OVERFLOW);//存储分配失败

S.top=S.base+S.stacksize;

S.stacksize+=STACKINCREMENT;

}

*S.top++=e;

returnOK;

}//Push2

StatusPop1(SqStack1&S,char&e){

//删除表达式栈的栈顶元素并用e返回

if(S.top==S.base)returnERROR;//栈空

e=*--S.top;

returnOK;

}//Pop1

StatusPop2(SqStack2&S,int&e){

//删除表达式栈的栈顶元素并用e返回

if(S.top==S.base)returnERROR;//栈空

e=*--S.top;

returnOK;

}//Pop2

StatusIn(intm,chara[]){

//判断m若是运算符,返回TRUE,否则返回FALSE

for(intn=0;a[n]!

='\0';n++)

if(m==a[n])returnTRUE;

returnFALSE;

}//In

charPrecede(charm,charn){

//判断m与n的优先级

switch(m){

case'+':

case'-':

if(n=='+'||n=='-'||n==')'||n=='=')

return'>';

elsereturn'<';break;

case'*':

case'/':

case'^':

case'%':

if(n=='(')

return'<';

elsereturn'>';break;

case'(':

if(n==')')

return'=';

elseif(n=='=')

returnERROR;

elsereturn'<';break;

case')':

if(n=='(')

returnERROR;

elsereturn'>';break;

case'=':

if(n=='=')

return'=';

elseif(n==')')

returnERROR;

elsereturn'<';break;

default:

returnERROR;break;//其他情况,表达式有误

}

}//Precede

intOperation(inta,chartheta,intb){

//运算函数

switch(theta){

case'+':

returna+b;break;

case'-':

returna-b;break;

case'*':

returna*b;break;

case'/':

returna/b;break;

case'%':

returna%b;break;

case'^':

returnpow(a,b);break;

default:

returnERROR;break;

}

}//Operation

intEvaluateExpression(charp[]){

//主要操作函数

inta,b,t;charx,theta,temp[10];

char*num=temp;char*ex=p;//声明指针

InitStack1(OPTR);Push1(OPTR,'=');

InitStack2(OPND);charc=*p;

while(c!

='='||GetTop1(OPTR)!

='='){

if(!

In(c,OP)){//不是运算符进数组

*(num++)=c;c=*(++ex);

if(In(c,OP)){//是运算符将数组压入栈

*num='\0';

t=atoi(temp);//将temp数组转化为整型数

num=temp;//指针指回数组头元素

Push2(OPND,t);

}

}

else

switch(Precede(GetTop1(OPTR),c)){

case'<':

//栈顶元素优先级低

Push1(OPTR,c);c=*(++ex);

break;

case'=':

//脱括号并接受下一字符

Pop1(OPTR,x);c=*(++ex);

break;

case'>':

//运算并将结果入栈

Pop1(OPTR,theta);

Pop2(OPND,b);Pop2(OPND,a);

Push2(OPND,Operation(a,theta,b));

break;

}

}

returnGetTop2(OPND);返回操作数栈顶元素

}//EvaluateExpression

(3)、主函数设计

intmain(){

//主函数

intresult;charexpression[100];//声明表达式数组

printf("Pleaseinputtheexpression:

");

gets(expression);//输入数组

result=EvaluateExpression(expression);

printf("theresultis:

%d\n",result);//输出结果

return0;

}

四、程序调试分析

1、开始时,使用getchar函数输入,但其有较大的弊端,只能输入0-9之间的整数,不能实现多位数及小数的计算。

于是换为gets函数,将表达式作为整体存入数组中待处理。

2、第一个问题解决后,出现了第二个问题:

数据结构混乱。

由于gets函数得到的是char型,直接存入操作数栈后,以ASCII码形式存入,使得编译通过但运行结果错误。

后来分析原因后,引入暂存数组,利用atoi函数,将数组中的数转化为整型,解决了这一问题。

3、在设计主要处理函数时,出现了多次编译错误。

后发现是由于指针指向混乱造成。

这主要是自己的思路不清,导致程序混乱。

后仔细绘制了流程图,详尽的分析了过程后,解决了该问题。

五、用户使用说明

1、本程序的运行环境为DOS操作系统,执行文件为:

Josegh.exe。

2、进入程序后,在Pleaseinputtheexpression:

后输入待求表达式,以“=”结尾,并敲回车。

3、程序运行后即在屏幕上输出计算结果。

六、程序运行结果

1、

2、

七、程序清单

#defineSTACK_INIT_SIZE100

#defineSTACKINCREMENT10

#defineOVERFLOW-2

#defineOK1

#defineERROR0

#defineTRUE1

#defineFALSE0

#include"stdio.h"

#include"stdlib.h"

#include"math.h"

typedefintStatus;

charOP[]={'+','-','*','/','(',')','^','%','='};//定义运算符数组

typedefstruct{

char*base;

char*top;

intstacksize;

}SqStack1;//定义运算符栈数据类型

typedefstruct{

int*base;

int*top;

intstacksize;

}SqStack2;//定义操作数栈数据类型

SqStack1OPTR;//声明运算符栈

SqStack2OPND;//声明操作数栈

StatusInitStack1(SqStack1&S){

//构造运算符栈

S.base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));

//申请空间

if(!

S.base)exit(OVERFLOW);//存储分配失败

S.top=S.base;

S.stacksize=STACK_INIT_SIZE;

returnOK;

}

StatusInitStack2(SqStack2&S){

//构造操作数栈

S.base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));

//申请空间

if(!

S.base)exit(OVERFLOW);//存储分配失败

S.top=S.base;

S.stacksize=STACK_INIT_SIZE;

returnOK;

}

charGetTop1(SqStack1S){

//取得运算符栈的栈顶元素

chare;

if(S.top==S.base)returnERROR;//栈空

e=*(S.top-1);

returne;

}

intGetTop2(SqStack2S){

//取得操作数栈的栈顶元素

inte;

if(S.top==S.base)returnERROR;//栈空

e=*(S.top-1);

returne;

}

StatusPush1(SqStack1&S,chare){

//插入元素e为运算符栈的栈顶元素

if(S.top-S.base>=S.stacksize){//栈满,追加存储空间

S.base=(char*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));

if(!

S.base)exit(OVERFLOW);//存储分配失败

S.top=S.base+S.stacksize;

S.stacksize+=STACKINCREMENT;

}

*S.top++=e;

returnOK;

}

StatusPush2(SqStack2&S,inte){

//插入元素e为操作数栈的栈顶元素

if(S.top-S.base>=S.stacksize){//栈满,追加存储空间

S.base=(int*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(int));

if(!

S.base)exit(OVERFLOW);//存储分配失败

S.top=S.base+S.stacksize;

S.stacksize+=STACKINCREMENT;

}

*S.top++=e;

returnOK;

}

StatusPop1(SqStack1&S,char&e){

//删除表达式栈的栈顶元素并用e返回

if(S.top==S.base)returnERROR;//栈空

e=*--S.top;

returnOK;

}

StatusPop2(SqStack2&S,int&e){

//删除表达式栈的栈顶元素并用e返回

if(S.top==S.base)returnERROR;//栈空

e=*--S.top;

returnOK;

}

StatusIn(intm,chara[]){

//判断m若是运算符,返回TRUE,否则返回FALSE

for(intn=0;a[n]!

='\0';n++)

if(m==a[n])returnTRUE;

returnFALSE;

}

charPrecede(charm,charn){

//判断m与n的优先级

switch(m){

case'+':

case'-':

if(n=='+'||n=='-'||n==')'||n=='=')

return'>';

elsereturn'<';break;

case'*':

case'/':

case'^':

case'%':

if(n=='(')

return'<';

elsereturn'>';break;

case'(':

if(n==')')

return'=';

elseif(n=='=')

returnERROR;

elsereturn'<';break;

case')':

if(n=='(')

returnERROR;

elsereturn'>';break;

case'=':

if(n=='=')

return'=';

elseif(n==')')

returnERROR;

elsereturn'<';break;

default:

returnERROR;break;//其他情况,表达式有误

}

}

intOperation(inta,chartheta,intb){

//运算函数

switch(theta){

case'+':

returna+b;break;

case'-':

returna-b;break;

case'*':

returna*b;break;

case'/':

returna/b;break;

case'%':

returna%b;break;

case'^':

returnpow(a,b);break;

default:

returnERROR;break;

}

}

intEvaluateExpression(charp[]){

//主要操作函数

inta,b,t;charx,theta,temp[10];

char*num=temp;char*ex=p;//声明指针

InitStack1(OPTR);Push1(OPTR,'=');

InitStack2(OPND);charc=*p;

while(c!

='='||GetTop1(OPTR)!

='='){

if(!

In(c,OP)){//不是运算符进数组

*(num++)=c;c=*(++ex);

if(In(c,OP)){//是运算符将数组压入栈

*num='\0';

t=atoi(temp);//将temp数组转化为整型数

num=temp;//指针指回数组头元素

Push2(OPND,t);

}

}

else

switch(Precede(GetTop1(OPTR),c)){

case'<':

//栈顶元素优先级低

Push1(OPTR,c);c=*(++ex);

break;

case'=':

//脱括号并接受下一字符

Pop1(OPTR,x);c=*(++ex);

break;

case'>':

//运算并将结果入栈

Pop1(OPTR,theta);

Pop2(OPND,b);Pop2(OPND,a);

Push2(OPND,Operation(a,theta,b));

break;

}

}

returnGetTop2(OPND);返回操作数栈顶元素

}

intmain(){

//主函数

intresult;charexpression[100];//声明表达式数组

printf("Pleaseinputtheexpression:

");

gets(expression);//输入数组

result=EvaluateExpression(expression);

printf("theresultis:

%d\n",result);//输出结果

return0;

}

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

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2