数据结构课程设计用两种方式实现表达式自动计算Word下载.docx

上传人:b****6 文档编号:17496086 上传时间:2022-12-06 格式:DOCX 页数:20 大小:128.74KB
下载 相关 举报
数据结构课程设计用两种方式实现表达式自动计算Word下载.docx_第1页
第1页 / 共20页
数据结构课程设计用两种方式实现表达式自动计算Word下载.docx_第2页
第2页 / 共20页
数据结构课程设计用两种方式实现表达式自动计算Word下载.docx_第3页
第3页 / 共20页
数据结构课程设计用两种方式实现表达式自动计算Word下载.docx_第4页
第4页 / 共20页
数据结构课程设计用两种方式实现表达式自动计算Word下载.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

数据结构课程设计用两种方式实现表达式自动计算Word下载.docx

《数据结构课程设计用两种方式实现表达式自动计算Word下载.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计用两种方式实现表达式自动计算Word下载.docx(20页珍藏版)》请在冰豆网上搜索。

数据结构课程设计用两种方式实现表达式自动计算Word下载.docx

流程图说明:

该流程图分两部分成,第一部分是中缀转后缀部分,第二部分是用于后缀表达式求值的。

(二)直接计算算法的流程图

图2接计算算法的流程图

该流程图进过图1改进得到,只是缺少中缀转后缀的部分。

三、源代码

下面给出的是用中缀转后缀算法实现的程序的源代码:

#include<

stdio.h>

#defineN50

typedefstructStackArray{

floatdata[N];

inttop;

}StackArray;

/*定义操作数栈*/

typedefstructStackChar{

chardata[N];

}StackChar;

/*定义操作符栈*/

StackArray*InitNum()/*初始化数值栈*/

{

StackArray*p=(StackArray*)malloc(sizeof(StackArray));

/*取一段内存赋予数值栈*/

p->

top=-1;

returnp;

/*返回*/

}

StackChar*InitChar()/*初始化操作符栈*/

StackChar*p=(StackChar*)malloc(sizeof(StackChar));

intPushNum(StackArray*p,floatvalue)/*定义入栈函数*/

if(p->

top<

50-1)

{

top+=1;

data[p->

top]=value;

/*栈顶*/

return1;

}

else

return0;

intPushChar(StackChar*p,charvalue)/*操作符入栈*/

/*入栈为栈顶*/

/*返回值*/

intPopNum(StackArray*p,float*value)/*操作数出栈*/

top>

=0)/*判断栈是否为空*/

*value=p->

top];

top-=1;

intPopChar(StackChar*p,char*q)/*操作符出栈函数*/

if(p->

=0)/*定义操作符栈*/

*q=p->

floatVisitNum(StackArray*p)/*定义数值栈遍历函数*/

top!

=-1)

returnp->

elsereturn0;

charvisitChar(StackChar*p)/*定义操作符栈遍历函数*/

intlevel(charc)/*优先级*/

switch(c)

case'

#'

:

/*#的优先级*/

+'

return1;

-'

/*‘-‘的优先级*/

*'

return2;

/'

('

return3;

/*(优先级*/

default:

return-1;

intstrLen(char*L)/*字符串长度函数*/

inti;

for(i=0;

L[i]!

='

\0'

;

i++);

/*循环条件*/

if(L[0]=='

||L[0]=='

{

i=i-1;

returni;

floatCompute(floata,charc,floatb)/*计算*/

returna+b;

/*加号的运算*/

returna-b;

returna*b;

/*乘号的运算*/

returna/b;

/*除号的运算*/

voidmain()

StackArray*data;

StackChar*op;

inti,j=0;

floatn;

floatresult,opA,opB;

charopChar;

chararray[N];

char*ptarray=NULL;

/*定义指针*/

floathouzhui[N];

printf("

Pleaseenteradata:

\t"

);

while((scanf("

%s"

array))!

=EOF)/*循环条件*/

op=InitChar();

data=InitNum();

PushChar(op,'

array[strLen(array)]='

/*结束标志*/

ptarray=array;

i<

strLen(ptarray);

i++)/*循环条件*/

if(array[i]>

=48&

&

array[i]<

=57||array[i]=='

.'

)/*判断数值

doubleweight=0.1;

intflag=0;

/*定义变量*/

floatn=0;

n=array[i]-48;

while(array[i+1]>

array[i+1]<

=57||array[i+1]=='

)/*判定数值*/

if(array[i+1]=='

)/*小数*/

flag=1;

if(flag==0)n=n*10+array[i+1]-48;

/*整数化浮点数*/

n=n+(array[i+1]-48)*weight;

/*小数化浮点数*/

weight*=0.1;

/*小数位权*/

i++;

houzhui[j]=n;

j++;

if(array[i]=='

)/*结束标志*/

while(visitChar(op)!

)/*对操作符栈遍历*/

PopChar(op,&

opChar);

houzhui[j]=opChar;

/*出栈入数组*/

if(level(array[i])>

level(visitChar(op))||

visitChar(op)=='

)/*判断优先级*/

PushChar(op,array[i]);

/*入栈*/

)'

)/*遇见字符‘)’*/

)/*出战到‘(’*/

j++;

/*操作符入数组*/

}

}else

while(level(array[i])<

=

level(visitChar(op)))/*优先级*/

/*出栈*/

/*运算符进栈*/

for(j=0;

houzhui[j]!

j++)

if((char)houzhui[j]=='

||(char)houzhui[j]=='

||

(char)houzhui[j]=='

)/*类型转换*/

%2c"

(char)houzhui[j]);

/*输出一个运算符*/

PopNum(data,&

opA);

opB);

result=Compute(opB,(char)houzhui[j],opA);

/*调用函数*/

PushNum(data,result);

/*结果入栈*/

PushNum(data,houzhui[j]);

%8f"

houzhui[j])/*输出后缀表达式*/;

\ntheResultis:

%.2f\n\n"

result);

/*输出结果*/

下面给出的是用直接计算算法实现的程序的源代码:

typedefstructlistStack

floatdata[N];

inttop;

}listStack;

/*定义存储操作数的栈*/

typedefstructopStack

chardata[N];

}opStack;

/*用于定义存储操作符号的栈*/

listStack*InitNum()/*初始化数值栈*/

listStack*p=(listStack*)malloc(sizeof(listStack));

top=-1;

/*定义栈底*/

returnp;

opStack*InitChar()/*初始化操作符栈*/

opStack*p=(opStack*)malloc(sizeof(opStack));

/*取一段内存赋予操作符栈*/

p->

top=-1;

intPushNum(listStack*p,floatvalue)/*定义入栈函数*/

N-1)

/*入栈的数值为栈顶元素*/

else

return0;

intPopNum(listStack*p,float*a)/*定义数值出栈函数*/

=0)/*判定栈不为空*/

*a=p->

floatVisitNum(listStack*p)/*定义数值栈遍历函数*/

=-1)/*判定栈是否为空*/

returnp->

elsereturn0;

voidPushChar(opStack*p,chara)/*定义操作符入栈函数*/

top]=a;

/*入栈字符为栈顶元素*/

else;

intPopChar(opStack*p,char*a)/*定义操作符出栈函数*/

charvisitChar(opStack*p)/*定义操作符栈遍历函数*/

/*返回栈顶的值*/

intstrLen(char*L)/*计算字符串长度*/

inti;

for(i=0;

/*循环条件的判定*/

if(L[0]=='

i=i-1;

returni;

intlevel(charc)/*符号的优先级*/

switch(c)

case'

default:

floatCompute(floata,charch,floatb)/*数据运算*/

switch(ch)

/*返回加号数值运算*/

/*返回减号数值运算*/

/*返回除号数值运算*/

return-1;

listStack*data;

/*定义操作数栈,由指针data指出*/

opStack*op;

/*对变量进行声明*/

floatn;

floatresult,opA,opB;

charoperand[2],opChar;

/*定义字符型数组和字符变量*/

chararray[N];

char*ptarray=NULL;

/*定义字符型指针*/

printf("

while((scanf("

=EOF)/*判断循环的条件*/

op=InitChar();

data=InitNum();

PushChar(op,'

/*将字符#赋予数组最后*/

ptarray=array;

i++)/*判定循环的条件*/

if(array[i]>

=57||

array[i]=='

)/*判断值*/

doubleweight=0.1;

intflag=0;

/*定义整形变量flag*/

/*定义浮点型变量*/

while(array[i+1]>

array[i+1]=='

flag=1;

/*读到小数点*/

/*将整数部分字符串转化为实数*/

/*将表示小数部分的字符也转化过来*/

weight*=0.1;

/*weight为小数位权*/

i++;

PushNum(data,n);

/*将数值进栈*/

)/*遇见字符#*/

while(visitChar(op)!

)/*对操作符栈进行遍历*/

PopChar(op,&

/*字符出栈*/

PopNum(data,&

/*数出栈*/

result=Compute(opB,opChar,opA);

/*调用运算函数*/

PushNum(data,result);

if(level(array[i])>

visitChar(op)=='

)/*判断操作符的优先级高低*/

PushChar(op,array[i]);

/*操作符进栈*/

)/*当操作符为)时*/

)/*遍历操作符栈*/

/*从数值栈输出一个值*/

result=Compute(opB,opChar,opA);

/*结果放回栈里*/

/*输出操作符*/

while(level(array[i])<

=level(visitChar(op)))/*判断操作符的优先级高低*/

/*从数值栈输出数值*/

esult=Compute(opB,opChar,opA);

/*将运算结果入栈*/

/*将操作符入栈*/

theResultis:

%.6f\n\n"

/*输出扫描一遍的运算结果*/

四、运行结果

(一)中缀转后缀算法的运行结果:

图3中缀转后缀算法的运行结果

(二)直接计算算法的运行结果:

图4直接计算算法的运行结果

五、遇到的问题及解决

这部分我主要遇到了如下两个问题,其内容与解决方法如下所列:

●问题1:

在遇到小数点处理的问题上,虽然说处理小数点的方法不是唯一的,但我在处理的时候只能计算一位小数,如果输入的是两位的话,计算结果的时候它就把一位小数后面的数据全丢了。

解决方法:

在输出后缀表达式的时候可以看到栈里存的数据最多只带一位小数,所以结果也只能出现一位小数。

因为在处理小数的时候我是让小数点后面的数乘以0.1,再加上前面的。

但如果是两位的话,那么最后的那一个是要乘以0.01的,也就是乘以0.1的自乘,所以在处理小数时我加了自乘的这行代码,运行的结果才真确的出来了。

●问题2:

无论输入什么表达式,不知道结果为什么始终是‘0.00‘,运行还是行的,有的时候程序只是按照扫到最后的一个运算符来执行。

图5运行出错

刚开始不知道哪儿出错了,就瞎找那些有可能会出现错的地方,比如:

能从图中直接看出来,没有后缀表达式;

计算结果也是错误的;

还有可能是哪个函数调用时出了错。

随后就从最简单的函数调用出错的问题开始检查,没有发现什么明显的错误,就放弃了这个问题,接着就是计算有没有出现简单的错误,因为它比较于中缀转后缀要简单一些,就开始试,单独的对这一段代码试,结果还是没发现什么错误,最后就剩下最难的中缀转后缀的问题了,如果这个也没有错,那就不知道哪儿出错了,就开始对它调试,看了两个小时也没找出来什么错误。

以后才找到那儿出了漏洞,原来缺少一句赋值语句“houzhui[j]=n;

”就成这样了,这个错误告诉我一点点的小错误也能导致整个程序的错误。

六、心得体会

通过这次的作业我充分的认识到了自己的不足,特别是对写程序代码这方面,一个程序从算法到用程序把它实现出来,这一整个过程是很不容易的,你懂得它的算法,不一定就能写的出来,通过这次我也深深的了这一点。

对于一个新手来说,小的错误出现的太多,而且一个小的错误就能让我束手无策,因为想不通错在哪,所以就一直在乱改,逻辑错误就更难了,有时候程序运行语法没有错误,但只要输入表达

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

当前位置:首页 > 医药卫生 > 预防医学

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

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