用两种方法实现表达式求值.docx

上传人:b****2 文档编号:2041080 上传时间:2022-10-26 格式:DOCX 页数:16 大小:133.54KB
下载 相关 举报
用两种方法实现表达式求值.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

用两种方法实现表达式求值

一、设计思想

一.中缀式计算结果的设计思想:

此种算法最主要是用了两个栈:

用两个栈来实现算符优先,一个栈用来保存需要计算的数据numStack(操作数栈),一个用来保存计算优先符priStack(操作符栈)。

从字符串中获取元素,如果是操作数,则直接进操作数栈,但如果获取的是操作符,则要分情况讨论,如下:

(这里讨论优先级时暂不包括“(”和“)”的优先级)

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

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

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

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

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

二.中缀转后缀及对后缀表达式计算的设计思想:

中缀转后缀时主要用了一个操作符栈和一个用来存放后缀表达式的栈,从表达式中依次获取元素,如果获取的是操作数,则直接存入s3栈中,如果获取的是操作符也需分情况讨论,如下:

(这里讨论优先级时暂不包括“(”和“)”的优先级)

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

2.如果获取的操作符a的优先级低于操作符栈栈顶元素b的优先级,则b出栈,a进栈,并且将b存入到操作符栈中;

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

4.如果获取的是“)”,则操作符栈的栈顶元素出栈,并依次存入到操作符栈中,直到操作符栈栈顶元素为“(”,然后将“(”出栈;

5.当表达式中的所有元素都入栈或存入到操作符栈之后,看操作符栈中是否还有元素,如果有,则依次出栈,并且依次存入到操作符栈中,最后打印操作符栈中的字符串,则此字符串即为要求的后缀表达式。

对后缀表达式的计算方法:

主要用到了一个操作数栈,从操作符栈中依次取出元素,如果是操作数,则进栈,如果是操作符,则从操作数栈中依次取出两个栈顶元素a1和a2,如果操作符是“/”,则计算a2/a1,将计算结果再次进栈,依此类推,最终栈顶元素即为计算的最终结果。

在这两种算法中,应该特别注意一点:

人的习惯,用户在输入表达式时,容易这样输入,如:

3*4(3+2),这样是不可取的,应必须要用户输入3*4*(3+2),这是在设计思想上错误提示的很重要一点,否则计算不全面!

二、算法流程图

第一个图是直接计算的流程图,图中反应除了这种方法的大致设计思路,但是有些细节没有反映出来,比如说,怎样把字符型数据转换为浮点型数据,就没有反映出来。

特别说明的是棱形左边代表Y,右边代表N,具体流程图如下:

图1直接计算算法流程图

第二个图是对后缀表达式的求值的算法流程图,同样,棱形左边代表Y,右边代表N,怎样把字符型数据转换为浮点型数据,也同样没有反映出来。

具体图如下:

图2后缀表达式计算的流程图

三、源代码

程序全部由java语言编写,用面向对象的思路解决,通过eclipe测试。

(一)用中缀式实现四则运算

利用栈,进行四则运算的类  

用两个栈来实现算符优先,一个栈用来保存需要计算的数据numStack,一个用来保存计算优先符priStack。

  

基本算法实现思路为:

用当前取得的运算符与priStack栈顶运算符比较优先级:

若高于,则因为会先运算,放入栈顶;  

若等于,因为出现在后面,所以会后计算,所以栈顶元素出栈,取出操作数运算;  

若小于,则同理,取出栈顶元素运算,将结果入操作数栈。

各个优先级'('>'*'='/'>'+'='-'>')'。

 

package.xiaoliu.zhongzhuishi;

importjava.util.Stack; 

 

//这个算法的表达式要以#结束 如:

21+5*1#

publicclassOperate{   

privateStackpriStack=newStack();//操作符栈   

privateStacknumStack=newStack();;//操作数栈   

 

/**  

*传入需要解析的字符串,返回计算结果(此处因为时间问题,省略合法性验证)  

*@paramstr需要进行技术的表达式  

*@return计算结果  

*/   

publicintcaculate(Stringstr){   

//1.判断string当中有没有非法字符   

Stringtemp;//用来临时存放读取的字符   

//2.循环开始解析字符串,当字符串解析完,且符号栈为空时,则计算完成   

StringBuffertempNum=newStringBuffer();//用来临时存放数字字符串(当为多位数时)   

StringBufferstring=newStringBuffer().append(str);//用来保存,提高效率   

 

while(string.length()!

=0){   

temp=string.substring(0,1);   

string.delete(0,1);   

//判断temp,当temp为操作符时   

if(!

isNum(temp)){   

//1.此时的tempNum内即为需要操作的数,取出数,压栈,并且清空tempNum   

if(!

"".equals(tempNum.toString())){   

//当表达式的第一个符号为括号   

intnum=Integer.parseInt(tempNum.toString());   

numStack.push(num); 

tempNum.delete(0,tempNum.length());   

}   

//用当前取得的运算符与栈顶运算符比较优先级:

若高于,则因为会先运算,放入栈顶;若等于,因为出现在后面,所以会后计算,所以栈顶元素出栈,取出操作数运算;   

//若小于,则同理,取出栈顶元素运算,将结果入操作数栈。

   

 

//判断当前运算符与栈顶元素优先级,取出元素,进行计算(因为优先级可能小于栈顶元素,还小于第二个元素等等,需要用循环判断)   

while(!

compare(temp.charAt(0))&&(!

priStack.empty())){  

inta=(int)numStack.pop();//第二个运算数   

intb=(int)numStack.pop();//第一个运算数   

charope=priStack.pop();   

intresult=0;//运算结果   

switch(ope){   

//如果是加号或者减号,则   

case'+':

   

result=b+a;   

//将操作结果放入操作数栈   

numStack.push(result);   

break;   

case'-':

   

result=b-a;   

//将操作结果放入操作数栈   

numStack.push(result);   

break;   

case'*':

   

result=b*a;   

//将操作结果放入操作数栈   

numStack.push(result);   

break;   

case'/':

   

result=b/a;//将操作结果放入操作数栈   

numStack.push(result);   

break;   

}   

 

}   

//判断当前运算符与栈顶元素优先级,如果高,或者低于平,计算完后,将当前操作符号,放入操作符栈   

if(temp.charAt(0)!

='#'){   

priStack.push(newCharacter(temp.charAt(0)));   

if(temp.charAt(0)==')'){//当栈顶为'(',而当前元素为')'时,则是括号内以算完,去掉括号   

priStack.pop();   

priStack.pop();   

}   

}   

}else   

//当为非操作符时(数字)   

tempNum=tempNum.append(temp);//将读到的这一位数接到以读出的数后(当不是个位数的时候)   

}   

returnnumStack.pop();   

}   

 

/**  

*判断传入的字符是不是0-9的数字  

*  

*@paramstr  

*      传入的字符串  

*@return  

*/   

privatebooleanisNum(Stringtemp){   

returntemp.matches("[0-9]");   

}   

 

/**  

*比较当前操作符与栈顶元素操作符优先级,如果比栈顶元素优先级高,则返回true,否则返回false  

*  

*@paramstr需要进行比较的字符  

*@return比较结果true代表比栈顶元素优先级高,false代表比栈顶元素优先级低  

*/   

privatebooleancompare(charstr){   

if(priStack.empty()){   

//当为空时,显然当前优先级最低,返回高   

returntrue;   

}   

charlast=(char)priStack.lastElement();   

//如果栈顶为'('显然,优先级最低,')'不可能为栈顶。

   

if(last=='('){   

returntrue;   

}   

switch(str){   

case'#':

   

returnfalse;//结束符   

case'(':

   

//'('优先级最高,显然返回true   

returntrue;   

case')':

   

//')'优先级最低,   

returnfalse;   

case'*':

{

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

当前位置:首页 > 工程科技 > 兵器核科学

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

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