用两种方法实现表达式求值Word文档下载推荐.docx
《用两种方法实现表达式求值Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《用两种方法实现表达式求值Word文档下载推荐.docx(16页珍藏版)》请在冰豆网上搜索。
![用两种方法实现表达式求值Word文档下载推荐.docx](https://file1.bdocx.com/fileroot1/2022-10/26/dd82a19a-f28d-48ba-a388-230c0af7e378/dd82a19a-f28d-48ba-a388-230c0af7e3781.gif)
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{
privateStack<
Character>
priStack=newStack<
();
//操作符栈
Integer>
numStack=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
"
.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;
result=b-a;
result=b*a;
result=b/a;
//判断当前运算符与栈顶元素优先级,如果高,或者低于平,计算完后,将当前操作符号,放入操作符栈
if(temp.charAt(0)!
='
#'
){
priStack.push(newCharacter(temp.charAt(0)));
if(temp.charAt(0)=='
){//当栈顶为'
,而当前元素为'
时,则是括号内以算完,去掉括号
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=='
switch(str){
returnfalse;
//结束符
//'
优先级最高,显然返回true
优先级最低,
{