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

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

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

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

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

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

数据结构(双语)

——项目文档报告

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

 

专业:

计算机科学与技术

班级:

14接计

指导教师:

姓名:

学号:

 

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

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

三、源代码………………………………………………………….06

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

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

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

 

一、设计思想

1.中缀转换后缀:

⑴定义两个栈S1,与S2。

S1主要管转换专用,S2主要管计算专用。

⑵扫描字符串,如果是字符或者小数的,直接进栈。

⑶如果是“(”,同直接进栈,直到遇到“)”,为止。

⑷开始处理运算符。

⑸如果栈定的运算符的优先级低于读到的那个,那么就直接进栈,否则把栈里的都进数组里。

⑹运算完,直到读完为止。

返回字符数组,后缀表达式就出来了。

⑺然后计算后缀表达。

⑻开始依次扫描数组,如果是数,就进栈,如果是运算符,那么就把栈的数弹出一个,赋值给一个变量,再弹一个赋值一个变量,再进行计算,完后再进栈。

⑼重复过程,直到度完。

栈顶元素就是最终结果。

⑽结束。

2.中缀直接计算:

⑴如果获取的操作符a的优先级高于操作符栈栈顶元素b的优先级,则a直接入操作符栈;

⑵如果获取的操作符a的优先级低于操作符栈栈顶元素b的优先级,则b出栈,a进栈,并且取出操作数栈的栈顶元素m,再取出操作数栈新的栈顶元素n,如果b为+,则用n+m,若为减号,则n-m,依此类推,并将所得结果入操作数栈;

⑶如果获取的是“(”,则直接进操作符栈;

⑸如果获取的是“)”,则操作符栈的栈顶元素出栈,做类似于情况2的计算,之后把计算结果入操作数栈,再取操作符栈顶元素,如果不是“(”,则出栈,重复操作,直到操作符栈顶元素为“(”,然后“(”出栈;

⑹当表达式中的所有元素都入栈后,看操作符栈中是否还有元素,如果有,则做类似于情况2的计算,并将结果存入操作数栈,则操作数栈中最终的栈顶元素就是所要求的结果。

 

二、算法流程图

1.后缀

 

2.中缀直接计算

 

三、源代码

1.后缀表达式

#include

#include

#include

#include

#include

#include

#include"fstream.h"

#defineMAXN1000

usingnamespacestd;

stackS1;//定义栈S1,转换专用

stackS2;//定义栈S2,计算专用

char*tranfExp(char*exp)//变换后缀

{

chartempStr[1000];//保存后缀表达式的字符串

charch;

inti=0,j=0;

inta=0;//标记表达式是否正确专用

///intb=0;//标记数字格式是否正确待用

while(exp[i]!

='\0')

{

if((exp[i]>='0'&&exp[i]<='9')||exp[i]=='.')//数字直接进字符串

{

tempStr[j++]=exp[i];

//tempStr[j]='';

}

elseif(exp[i]=='(')//左括号蹦进栈S1

{

S1.push(exp[i]);

}

elseif(exp[i]==')')//如果是右括号,就把左括号后面的运算符都进字符串

{

while(S1.empty()==false)

{

tempStr[j++]=S1.top();//括号里进数组

S1.pop();//进一个,蹦一个

if(S1.top()=='(')

{

S1.pop();//蹦出去‘(’

break;

}

}

}

elseif(exp[i]=='+'||exp[i]=='-')//如果遇到了加后者减号

{

while(S1.empty()==false)

{

ch=S1.top();

if(ch=='+'||ch=='-'||ch=='(')//与栈顶比较优先级,同级直接进栈

{

S1.push(exp[i]);

break;

}

else//不同级,S1栈里的东西都进字符串里

{

while(S1.empty()==false)

{

tempStr[j++]=S1.top();//进一个,蹦一个

S1.pop();

if(S1.top()=='(')//如果有括号就把括号前面的进串,括号后的不进

break;}

}

}

if(S1.empty()==true)//如果S1里的东西都进字符串了,变成空了,就把扫描遇到的东西,蹦进S1

{S1.push(exp[i]);}

}

elseif(exp[i]=='*'||exp[i]=='/')

{

S1.push(exp[i]);

}

else

{

printf("你输入的不对!

!

!

");

a=1;

break;//异常处理

}

i++;

}

while(S1.empty()==false)//最后把S1中的所有运算符弹出栈

{if(a==1)

{break;}

else

{tempStr[j++]=S1.top();//进一个,蹦一个

S1.pop();}

}

tempStr[j]='\0';//最后一个赋值为空字符串结束的标志

if(a==1)

return0;

else

returntempStr;//返回得到的后缀表达式

}

doublecalcExp(char*exp)//计算

{

inti=0;

while(exp[i]!

='\0')

{

if((exp[i]>='0'&&exp[i]<='9')||exp[i]=='.')//把数进栈S2,遇到运算符,就弹2个数计算,结果再进S2

{

if(exp[i]=='.')//小数处理专用

{

doublex=0;

doubley=0;

x=S2.top();

printf("X的值%f\n",x);

S2.pop();

i++;

y=exp[i]-'0';

printf("y的值%f\n",y);

x=x+y/10;

printf("X的值%f\n",x);

S2.push(x);

}

else

{S2.push(exp[i]-'0');}

printf("进栈计算的数%f\n",S2.top());

}

elseif(exp[i]=='-')

{

doublem=S2.top();

S2.pop();

doublen=S2.top();

S2.pop();

S2.push(n-m);

}

elseif(exp[i]=='+')

{

doublem=S2.top();

//printf("M的值%d\n",m);

S2.pop();

doublen=S2.top();

//printf("N的值%d\n",n);

S2.pop();

S2.push(n+m);

}

elseif(exp[i]=='/')

{

doublem=S2.top();

S2.pop();

doublen=S2.top();

S2.pop();

S2.push(n/m);

}

elseif(exp[i]=='*')

{

doublem=S2.top();

S2.pop();

doublen=S2.top();

S2.pop();

S2.push(n*m);

}

i++;

}

returnS2.top();

}

main()

{

charstr[1000];

charstr1[1000];

char*tranStr;

intlen;

doublerel;//最后结果

tranStr=(char*)malloc(100*sizeof(char));

printf("输入字符\n");

scanf("%s",str);

printf("转换成后缀表达式\n");

tranStr=tranfExp(str);

len=strlen(tranStr);

puts(tranStr);

for(inti=0;i<=len;i++)//直接传tranStr会发生莫名其妙的错误,所以重新定义了个数组,把串全传送过去

{str1[i]=tranStr[i];}

rel=calcExp(str1);

printf("结果为%f\n",rel);

}

 

2.中缀直接计算

#include

#include

#include

usingnamespacestd;

inttransform(chars[],charstored[])//转化

{

constinta[8]={-1,-1,2,1,0,1,0,2};//保存优先级

inti,j,temp;

stacksk;

for(i=0,j=0,temp=0;s[i]!

='\0';i++)//j保存数组stored的有效数字的长度

{

if(s[i]>='0'&&s[i]<='9')

temp=temp*10+s[i]-'0';

else

{

if(temp!

=0)

{

stored[j++]=temp+'0';

temp=0;

}

if(!

sk.empty()&&sk.top()==')')//弹出)

sk.pop();

if(sk.empty())//空就压入

sk.push(s[i]);

else

{

if(a[s[i]-'(']==a[sk.top()-'('])//这里看看ASCii表就明白了

{

stored[j++]=sk.top();

sk.pop();

sk.push(s[i]);

}

else

{

if((a[s[i]-'(']

='(')||s[i]==')')

{

while(!

sk.empty()&&sk.top()!

='(')//停止标志

{

stored[j++]=sk.top();

sk.pop();

}

if(!

sk.empty())

sk.pop();

sk.push(s[i]);

}

else

sk.push(s[i]);

}

}

}

}

stored[j++]=temp+'0';//最后的数字也要拿

while(!

sk.empty())//残余运算符

{

stored[j++]=sk.top();

sk.pop();

}

returnj;

}

intcalcular(charstored[],intn)

{

stackcal;

inti,x,y,result=0;

for(i=0;i

{

if(stored[i]=='+'||stored[i]=='-'||stored[i]=='*'||stored[i]=='/')//遇到运算符

{

y=cal.top();

cal.pop();

x=cal.top();

cal.pop();

switch(stored[i])//各种运算

{

case'+':

result=x+y;break;

case'-':

result=x-y;break;

case'*':

result=x*y;break;

case'/':

result=x/y;

}

cal.push(result);//保存当前结果

}

else

cal.push(stored[i]-'0');

}

returnresult;

}

intmain()

{

chars[1000];

charstored[1000];

intn,result;

while(cin>>s)

{

n=transform(s,stored);

result=calcular(stored,n);

cout<

}

return0;

}

 

四、运行结果

1.后缀

输入

结果

 

2.中缀直接计算

输入

结果

五、遇到的问题及解决

经过一个星期的写代码,我遇到了很多问题,并一一解决了,比如一些莫名其名的错误,都是思路没问题,但是呢,都是逻辑错误。

还有就是老师提问的,分隔符问题。

不过可以解决,但是呢,要大量的改代码,我怕时间不够了,就不改了,因为还要去弄下一个报告了。

算法不一定是程序,但程序一定是算法!

六、心得体会

在做完本项目之后,体会最深的就是应该细心,并且很多时候我们看见某些事情很简单就不想去做,而做的时候又总会遗漏很多需要考虑的细节,或者根本就不知道从哪入手更好,在做这个项目时,错过很多次,很多时候有一种成功离自己很近很近,似乎可以看到,但就是无法接触到的感觉,我想,在以后的学习中,应该把一些必要的程序都敲一遍,而不要直接说句,简单,然后不屑去做,这样,其实最终很难真正学到什么!

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

当前位置:首页 > 自然科学

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

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