用两种方式实现表达式自动计算.docx

上传人:b****6 文档编号:7310725 上传时间:2023-01-22 格式:DOCX 页数:22 大小:148.93KB
下载 相关 举报
用两种方式实现表达式自动计算.docx_第1页
第1页 / 共22页
用两种方式实现表达式自动计算.docx_第2页
第2页 / 共22页
用两种方式实现表达式自动计算.docx_第3页
第3页 / 共22页
用两种方式实现表达式自动计算.docx_第4页
第4页 / 共22页
用两种方式实现表达式自动计算.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

用两种方式实现表达式自动计算.docx

《用两种方式实现表达式自动计算.docx》由会员分享,可在线阅读,更多相关《用两种方式实现表达式自动计算.docx(22页珍藏版)》请在冰豆网上搜索。

用两种方式实现表达式自动计算.docx

用两种方式实现表达式自动计算

数据结构(双语)

——项目文档报告

用两种方式实现表达式自动计算

 

专业:

计算机科学与技术应用

班级:

*******

姓名:

学号:

 

一、设计思想……………………………………………………….01

二、算法流程图…………………………………………………….01

三、源代码………………………………………………………….03

四、运行结果……………………………………………………….15

五、遇到的问题及解决…………………………………………….16

六、心得体会……………………………………………………….17

 

一、设计思想

A:

中缀表达式转后缀表达式的设计思想:

我们借助计算机计算一个算数表达式的值,而在计算机中,算术表达式是由常量,变量,运算符和括号组成。

由于运算符的优先级不同又要考虑括号。

所以表达式不可能严格的从左到右进行,因此我们借助栈和数组来实现表达式的求值。

栈分别用来存储操作数和运算符。

在计算表达式的值之前,首先要把有括号的表达式转换成与其等值的无括号的表达式,也就是通常说的中缀表达式转后缀表达式。

在这个过程中,要设计两个栈,一个浮点型的存储操作数,用以对无符号的表达式进行求值。

另一个字符型的用来存储运算符,用以将算术表达式变成无括号的表达式;我们要假设运算符的优先级:

(),*/,+-。

首先将一标识号‘#’入栈,作为栈底元素;接着从左到右对算术表达式进行扫描。

每次读一个字符,若遇到左括号‘(’,则进栈;若遇到的是操作数,则立即输出;若又遇到运算符,如果它的优先级比栈顶元素的优先级数高的话,则直接进栈,否则输出栈顶元素,直到新的栈顶元素的优先级数比它低的,然后将它压栈;若遇到是右括号‘)’,则将栈顶的运算符输出,直到栈顶的元素为‘(’,然后,左右括号互相底消;如果我们设计扫描到‘#’的时候表示表达式已经扫描完毕,表达式已经全部输入,将栈中的运算符全部输出,删除栈底的标识号。

以上完成了中缀表达式转后缀表达式,输出无括号的表达式,若遇数值,操作数进栈;若遇运算符,让操作数栈的栈顶和次栈顶依次出栈并与此运算符进行运算,运算结果入操作数栈;重复以上的步骤,直到遇到‘#’,则此时栈中的结果便是所求的后缀表达式的值,接着输出结果。

以上就是设计这个算法的主要的思想。

设计思想的流程图详见图A;

B:

直接计算表达式的值。

所谓的扫一遍就是当扫完一个表达式结果也就计算出来了,是在上面扫两遍的思想进行修改的得来,首先,我们要建立两个栈,一个为字符型的用来存放运算符,另一个浮点型的用来存放操作数。

我们开始对表达式进行扫描,首先我们要假设运算符的优先级:

(),*/,+-。

如果扫描到的是数字符号,把它们转换成浮点型数据,存入操作数栈中。

如果扫描到的是运算符号,第一个运算符进栈,遇到‘(’存入运算符栈中,我们按照第一种算法的方法将表达式依次扫描。

只不过不同的是,当每取得的一个运算符的时候,都要与栈顶的运算符进行比较,如果它的优先级小于栈顶运算符优先级时,取出栈顶运算符并从操作数栈中取栈顶两个数进行运算,得到的结果则要存回操作数栈,就这样边扫描边比较,再进行计算。

遇到“)”对运算符的处理相同。

扫描结束后,把运算符栈的元素和操作数栈里的数进行运算。

每次的运算结果再放入操作数栈,一直到计算到运算符栈空。

最后操作数栈的栈顶留下的操作数即表达式的计算结果。

以上就是设计这个扫一遍算法的主要的思想。

设计思想的流程图详见图B;

二、算法流程图

 

A:

以下是中缀转后缀算法的流程图

图2是中缀转后缀算法的流程图

 

B:

以下是扫一遍代码运算的流程图:

图B是直接计算的流程图

三、源代码

A:

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

#include/*I/O函数*/

#include

#include

#defineMAXLEN100/*对栈的最大存贮值进行定义*/

/*自定义两个栈*/

typedefstructstackData{

floatdata[MAXLEN];

inttop;/*指针*/

}stackData;/*定义存储操作数的栈*/

typedefstructstackChar{

chardata[MAXLEN];

inttop;/*指针*/

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

 

/*对相应的函数和常量变量,指针进行声明*/

intjudgeFirst(charc);/*声明判定操作符优先级的函数*/

intPushNum(stackData*p,floatvalue);/*入栈*/

intPushChar(stackChar*p,charvalue);

intPopNum(stackData*p,float*value);/*出栈*/

intPopChar(stackChar*p,char*value);

floatVisitNum(stackData*p);

charvisitChar(stackChar*p);

floatCompute(floata,charch,floatb);/*操作函数,执行具体运算*/

intCheck(char*);

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

stackChar*Operation;

stackData*InitNum();

stackChar*InitChar();

inti,j=0;

floatbl,blo;/*对变量进行声明*/

floatresoult,opA,opB;

charoperand[2],opChar;/*定义字符型数组和字符变量*/

charrecv[MAXLEN];

floatsuffix[MAXLEN];

char*ptRecv=NULL;/*定义字符型指针*/

intmain()/*主函数*/

{

 

printf("pleaseentertneformula:

");

while((scanf("%s",recv))!

=EOF)/*判断循环的条件当输入EOF的时候停止*/

{

Operation=InitChar();

Data=InitNum();

PushChar(Operation,'#');

recv[strLen(recv)]='#';/*将字符#赋予数组最后*/

ptRecv=recv;

for(i=0;i

{

if(recv[i]>='0'&&recv[i]<='9'||recv[i]=='.')/*判断数值*/

{

doubleweight=0.1;

intflag=0;/*定义变量flag,用来标志小数点*/

floatblo=0;/*定义浮点型变量*/

blo=recv[i]-'0';

while(recv[i+1]>='0'&&recv[i+1]<='9'||recv[i+1]=='.')/*判定数值*/

{

if(recv[i+1]=='.')/*读到小数点*/

flag=1;

else

{

if(flag==0)blo=blo*10+recv[i+1]-'0';/*将整数部分字符串转化为实数*/

else

{

blo=blo+(recv[i+1]-'0')*weight;/*将表示小数部分的字符也转化过来*/

weight*=0.1;/*weight为小数位权*/

}

}

i++;

}

suffix[j]=blo;j++;/*数值进入数组*/

}

else

{

if(recv[i]=='#')/*遇见字符#*/

{

while(visitChar(Operation)!

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

{

PopChar(Operation,&opChar);

suffix[j]=opChar;

j++;/*字符出栈进入数组*/

}

}

else

{

if(judgeFirst(recv[i])>judgeFirst(visitChar(Operation))||visitChar(Operation)=='(')/*判断操作符的优先级高低*/

{

PushChar(Operation,recv[i]);/*字符入栈*/

}

else

{

if(recv[i]==')')/*遇见字符)*/

{

while(visitChar(Operation)!

='(')/*输出(之前的所有操作符*/

{

PopChar(Operation,&opChar);

suffix[j]=opChar;

j++;/*操作符进入数组*/

}

PopChar(Operation,&opChar);

}else

{

while(judgeFirst(recv[i])<=judgeFirst(visitChar(Operation)))/*进栈的运算符优先级低时,先出栈后进栈*/

{

PopChar(Operation,&opChar);

suffix[j]=opChar;/*出栈的进入数组*/

j++;

}

PushChar(Operation,recv[i]);/*运算符进栈*/

}

}

}

}

}

printf("thesuffixis:

");/*输出后缀表达式*/

for(j=0;suffix[j]!

='\0';j++)

{

if((char)suffix[j]=='+'||(char)suffix[j]=='-'||(char)suffix[j]=='*'||(char)suffix[j]=='/')/*强制类型转换*/

{

printf("%6c",(char)suffix[j]);/*输出一个运算符*/

PopNum(Data,&opA);

PopNum(Data,&opB);

resoult=Compute(opB,(char)suffix[j],opA);/*调用函数进行运算*/

PushNum(Data,resoult);/*运算结果入栈*/

}else

{

PushNum(Data,suffix[j]);

printf("%10f",suffix[j])/*输出后缀表达式*/;

}

}

printf("\ntheResultis:

%.2f\n\n",resoult);/*输出运算结果*/

}

return0;

}

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

{

stackData*p=(stackData*)malloc(sizeof(stackData));/*取一段内存赋予数值栈*/

p->top=-1;/*定义栈底*/

returnp;/*返回数值栈*/

}

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

{

stackChar*p=(stackChar*)malloc(sizeof(stackChar));/*取一段内存赋予操作符栈*/

p->top=-1;

returnp;

}

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

{

if(p->top

{

p->top+=1;/*指针*/

p->data[p->top]=value;/*入栈的数值为栈顶元素*/

return1;

}

else

{

return0;

}

}

intPushChar(stackChar*p,charvalue)/*定义操作符入栈函数*/

{

if(p->top

{

p->top+=1;/*指针*/

p->data[p->top]=value;/*入栈字符为栈顶元素*/

return1;

}

else

{

return0;/*栈溢出返回0*/

}

}

intPopNum(stackData*p,float*value)/*定义数值出栈函数*/

{

if(p->top>=0)/*判定栈不为空*/

{

*value=p->data[p->top];

p->top-=1;/*指针*/

}

return1;

}

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

{

if(p->top>=0)/*判定栈不为空*/

{

*value=p->data[p->top];

p->top-=1;/*指针*/

}

return1;

}

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

{

if(p->top!

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

returnp->data[p->top];

elsereturn0;

}

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

{

if(p->top!

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

returnp->data[p->top];

elsereturn0;

}

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

{

switch(c)

{

case'#':

return0;/*#的优先级*/

case'+':

return1;

case'-':

return1;/*减号的优先级*/

case'*':

return2;

case'/':

return2;

case'(':

return3;/*左括号的优先级*/

default:

return-1;

}

}

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

{

inti=0;

for(;L[i]!

='\0';i++);/*循环条件的判定*/

if(L[0]=='-'||L[0]=='+')

{

i=i-1;

}

returni;

}

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

{

switch(ch)

{

case'+':

returna+b;/*返回加号数值运算结果*/

case'-':

returna-b;

case'*':

returna*b;/*返回乘号数值运算结果*/

case'/':

returna/b;/*返回除号数值运算*/

default:

return-1;}

}

B:

下面给出的是直接计算的思想的代码实现:

#include/*I/O函数*/

#include

#include

#defineMAXLEN100/*对栈的最大存储值进行声明*/

/*声明用来存储操作数和运算符的栈*/

typedefstructstackData

{

floatdata[MAXLEN];

inttop;

}stackData;/*定义操作数的栈*/

 

typedefstructstackChar

{

chardata[MAXLEN];

inttop;

}stackChar;/*用于定义运算符的栈*/

 

/*对函数进行声明*/

intjudgeFirst(charc);/*声明判定操作符优先级的函数*/

charvisitChar(stackChar*p);

intpushNum(stackData*p,floatvalue);/*操作数入栈*/

intPushChar(stackChar*p,charvalue);/*运算符入栈*/

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

intPopChar(stackChar*p,char*value);/*运算符出栈*/

floatVisitNum(stackData*p);

floatCompute(floata,charch,floatb);/*操作函数,执行具体运算*/

 

intmain()/*主函数*/

{

stackData*InitNum();

stackChar*InitChar();

intCheck(char*);

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

stackChar*Operation;/*定义运算符栈,由指针Operation指出*/

inti;/*对变量进行声明*/

floatdit,digit;

floatresoult,opA,opB;

charoperand[2],opChar;/*定义字符型数组和字符变量*/

charrecv[MAXLEN];

char*ptRecv=NULL;/*定义字符型指针*/

printf("pleaseentertheformula:

");

while((scanf("%s",recv))!

=EOF)/*判断循环的条件当输入EOF的时候停止*/

{

Data=InitNum();

Operation=InitChar();

PushChar(Operation,'#');

recv[strLen(recv)]='#';/*将字符#赋予数组最后*/

ptRecv=recv;

for(i=0;i

{

if(recv[i]>='0'&&recv[i]<='9'||recv[i]=='.')/*判断值*/

{

doubleweight=0.1;

intflag=0;/*定义整形变量flag,记录是否有小数点*/

floatdigit=0;/*定义浮点型变量*/

digit=recv[i]-'0';

while(recv[i+1]>='0'&&recv[i+1]<='9'||recv[i+1]=='.')/*判定数值*/

{

if(recv[i+1]=='.')/*读到小数点*/

flag=1;

else

{

if(flag==0)digit=digit*10+recv[i+1]-'0';/*将整数部分字符串转化为实数*/

else

{

digit=digit+(recv[i+1]-'0')*weight;/*将表示小数部分的字符也转化过来*/

weight*=0.1;/*weight为小数位权*/

}

}

i++;

}

pushNum(Data,digit);/*将数值进栈*/

}

else

{

if(recv[i]=='#')/*遇见字符#*/

{

while(visitChar(Operation)!

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

{

PopChar(Operation,&opChar);/*字符出栈*/

PopNum(Data,&opA);

PopNum(Data,&opB);/*数出栈*/

resoult=Compute(opB,opChar,opA);/*调用运算函数*/

pushNum(Data,resoult);

}

}

else

{

if(judgeFirst(recv[i])>judgeFirst(visitChar(Operation))||visitChar(Operation)=='(')/*判断操作符的优先级高低*/

{

PushChar(Operation,recv[i]);/*操作符进栈*/

}

else

{

if(recv[i]==')')/*当操作符为)时*/

{

while(visitChar(Operation)!

='(')/*遍历操作符栈*/

{

PopChar(Operation,&opChar);

PopNum(Data,&opA);

PopNum(Data,&opB);/*从数值栈输出一个值*/

resoult=Compute(opB,opChar,opA);

pushNum(Data,resoult);/*结果放回栈里*/

}

PopChar(Operation,&opChar);/*输出操作符*/

}else

{

while(judgeFirst(recv[i])<=judgeFirst(visitChar(Operation)))/*判断操作符的优先级高低*/

{

PopChar(Operation,&opChar);

PopNum(Data,&opA);/*从数值栈输出数值*/

PopNum(Data,&opB);

resoult=Compute(opB,opChar,opA);/*调用运算函数*/

pushNum(Data,resoult);/*将运算结果入栈*/

}

PushChar(Operation,recv[i]);/*将操作符入栈*/

}

}

}

}

}

printf("\ntheResultis:

%.2f\n\n",resoult);/*输出扫描一遍的运算结果*/

}

return0;

}

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

{

stackData*p;

p=(stackData*)malloc(sizeof(stackData));/*取一段内存赋予数值栈*/

p->top=-1;/*定义栈底*/

returnp;/*返回数值栈*/

}

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

{

stackChar*p=(stackChar*)malloc(sizeof(stackChar));/*取一段内存赋予操作符栈*/

p->top=-1;

returnp;

}

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

当前位置:首页 > 高等教育 > 研究生入学考试

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

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