用两种方式实现表达式自动计算文档格式.docx
- 文档编号:20418865
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:22
- 大小:148.93KB
用两种方式实现表达式自动计算文档格式.docx
《用两种方式实现表达式自动计算文档格式.docx》由会员分享,可在线阅读,更多相关《用两种方式实现表达式自动计算文档格式.docx(22页珍藏版)》请在冰豆网上搜索。
如果我们设计扫描到‘#’的时候表示表达式已经扫描完毕,表达式已经全部输入,将栈中的运算符全部输出,删除栈底的标识号。
以上完成了中缀表达式转后缀表达式,输出无括号的表达式,若遇数值,操作数进栈;
若遇运算符,让操作数栈的栈顶和次栈顶依次出栈并与此运算符进行运算,运算结果入操作数栈;
重复以上的步骤,直到遇到‘#’,则此时栈中的结果便是所求的后缀表达式的值,接着输出结果。
以上就是设计这个算法的主要的思想。
设计思想的流程图详见图A;
B:
直接计算表达式的值。
所谓的扫一遍就是当扫完一个表达式结果也就计算出来了,是在上面扫两遍的思想进行修改的得来,首先,我们要建立两个栈,一个为字符型的用来存放运算符,另一个浮点型的用来存放操作数。
我们开始对表达式进行扫描,首先我们要假设运算符的优先级:
如果扫描到的是数字符号,把它们转换成浮点型数据,存入操作数栈中。
如果扫描到的是运算符号,第一个运算符进栈,遇到‘(’存入运算符栈中,我们按照第一种算法的方法将表达式依次扫描。
只不过不同的是,当每取得的一个运算符的时候,都要与栈顶的运算符进行比较,如果它的优先级小于栈顶运算符优先级时,取出栈顶运算符并从操作数栈中取栈顶两个数进行运算,得到的结果则要存回操作数栈,就这样边扫描边比较,再进行计算。
遇到“)”对运算符的处理相同。
扫描结束后,把运算符栈的元素和操作数栈里的数进行运算。
每次的运算结果再放入操作数栈,一直到计算到运算符栈空。
最后操作数栈的栈顶留下的操作数即表达式的计算结果。
以上就是设计这个扫一遍算法的主要的思想。
设计思想的流程图详见图B;
二、算法流程图
以下是中缀转后缀算法的流程图
图2是中缀转后缀算法的流程图
B:
以下是扫一遍代码运算的流程图:
图B是直接计算的流程图
三、源代码
A:
下面给出的是用中缀表达式转后缀表达式算法实现的程序的源代码:
#include<
stdio.h>
/*I/O函数*/
malloc.h>
stdlib.h>
#defineMAXLEN100/*对栈的最大存贮值进行定义*/
/*自定义两个栈*/
typedefstructstackData{
floatdata[MAXLEN];
inttop;
/*指针*/
}stackData;
/*定义存储操作数的栈*/
typedefstructstackChar{
chardata[MAXLEN];
}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<
strLen(ptRecv);
i++)/*扫描表达式,判断循环的条件*/
if(recv[i]>
='
0'
&
&
recv[i]<
9'
||recv[i]=='
.'
)/*判断数值*/
doubleweight=0.1;
intflag=0;
/*定义变量flag,用来标志小数点*/
floatblo=0;
/*定义浮点型变量*/
blo=recv[i]-'
while(recv[i+1]>
recv[i+1]<
||recv[i+1]=='
)/*判定数值*/
if(recv[i+1]=='
)/*读到小数点*/
flag=1;
else
if(flag==0)blo=blo*10+recv[i+1]-'
/*将整数部分字符串转化为实数*/
else
blo=blo+(recv[i+1]-'
)*weight;
/*将表示小数部分的字符也转化过来*/
weight*=0.1;
/*weight为小数位权*/
}
i++;
suffix[j]=blo;
j++;
/*数值进入数组*/
if(recv[i]=='
)/*遇见字符#*/
while(visitChar(Operation)!
)/*对操作符栈进行遍历*/
PopChar(Operation,&
opChar);
suffix[j]=opChar;
j++;
/*字符出栈进入数组*/
{
if(judgeFirst(recv[i])>
judgeFirst(visitChar(Operation))||visitChar(Operation)=='
('
)/*判断操作符的优先级高低*/
PushChar(Operation,recv[i]);
/*字符入栈*/
)'
)/*遇见字符)*/
while(visitChar(Operation)!
)/*输出(之前的所有操作符*/
PopChar(Operation,&
/*操作符进入数组*/
}
}else
while(judgeFirst(recv[i])<
=judgeFirst(visitChar(Operation)))/*进栈的运算符优先级低时,先出栈后进栈*/
/*出栈的进入数组*/
/*运算符进栈*/
thesuffixis:
/*输出后缀表达式*/
for(j=0;
suffix[j]!
\0'
j++)
if((char)suffix[j]=='
+'
||(char)suffix[j]=='
-'
*'
/'
)/*强制类型转换*/
%6c"
(char)suffix[j]);
/*输出一个运算符*/
PopNum(Data,&
opA);
opB);
resoult=Compute(opB,(char)suffix[j],opA);
/*调用函数进行运算*/
PushNum(Data,resoult);
/*运算结果入栈*/
PushNum(Data,suffix[j]);
%10f"
suffix[j])/*输出后缀表达式*/;
\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));
/*取一段内存赋予操作符栈*/
intPushNum(stackData*p,floatvalue)/*定义入栈函数*/
if(p->
top<
MAXLEN-1)
top+=1;
data[p->
top]=value;
/*入栈的数值为栈顶元素*/
return1;
intPushChar(stackChar*p,charvalue)/*定义操作符入栈函数*/
MAXLEN-1)/*栈不能满*/
/*入栈字符为栈顶元素*/
/*栈溢出返回0*/
intPopNum(stackData*p,float*value)/*定义数值出栈函数*/
top>
=0)/*判定栈不为空*/
*value=p->
top];
top-=1;
intPopChar(stackChar*p,char*value)/*定义操作符出栈函数*/
=0)/*判定栈不为空*/
/*指针*/
floatVisitNum(stackData*p)/*定义数值栈遍历函数*/
top!
=-1)/*判定栈是否为空*/
returnp->
elsereturn0;
charvisitChar(stackChar*p)/*定义操作符栈遍历函数*/
intjudgeFirst(charc)/*符号的优先级*/
switch(c)
case'
:
/*#的优先级*/
return1;
/*减号的优先级*/
return2;
return3;
/*左括号的优先级*/
default:
return-1;
intstrLen(char*L)/*计算字符串长度*/
inti=0;
for(;
L[i]!
i++);
/*循环条件的判定*/
if(L[0]=='
||L[0]=='
)
i=i-1;
returni;
floatCompute(floata,charch,floatb)/*数据运算*/
switch(ch)
returna+b;
/*返回加号数值运算结果*/
returna-b;
returna*b;
/*返回乘号数值运算结果*/
returna/b;
/*返回除号数值运算*/
下面给出的是直接计算的思想的代码实现:
#defineMAXLEN100/*对栈的最大存储值进行声明*/
/*声明用来存储操作数和运算符的栈*/
typedefstructstackData
/*定义操作数的栈*/
typedefstructstackChar
/*用于定义运算符的栈*/
/*对函数进行声明*/
intpushNum(stackData*p,floatvalue);
/*操作数入栈*/
/*运算符入栈*/
/*操作数出栈*/
/*运算符出栈*/
/*定义操作数栈,由指针data指出*/
/*定义运算符栈,由指针Operation指出*/
inti;
floatdit,digit;
printf("
pleaseentertheformula:
for(i=0;
i++)/*判定循环的条件*/
)/*判断值*/
/*定义整形变量flag,记录是否有小数点*/
floatdigit=0;
digit=recv[i]-'
if(recv[i+1]=='
flag=1;
if(flag==0)digit=digit*10+recv[i+1]-'
digit=digit+(recv[i+1]-'
)*weight;
pushNum(Data,digit);
/*将数值进栈*/
/*字符出栈*/
/*数出栈*/
resoult=Compute(opB,opChar,opA);
/*调用运算函数*/
pushNum(Data,resoult);
)/*判断操作符的优先级高低*/
/*操作符进栈*/
)/*当操作符为)时*/
)/*遍历操作符栈*/
/*从数值栈输出一个值*/
/*结果放回栈里*/
/*输出操作符*/
=judgeFirst(visitChar(Operation)))/*判断操作符的优先级高低*/
/*从数值栈输出数值*/
/*将运算结果入栈*/
/*将操作符入栈*/
/*输出扫描一遍的运算结果*/
stackData*p;
p=(stackData*)malloc(sizeof(stackData));
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 用两种 方式 实现 表达式 自动 计算