java 栈 表达式求值_数据结构(java语言描述)链栈的使用——表达式求值

本文介绍了如何使用Java通过链栈实现中缀表达式转换为后缀表达式,并对后缀表达式进行计算求值。详细讲解了转换过程和计算方法,包括括号处理、运算符优先级以及后缀表达式的优点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.操作思想

首先将表达式转换为后缀表达式的形式;

然后利用链栈存储后缀表达式,利用栈的入栈、出栈计算表达式。

2.把中缀表达式转换为后缀表达式

初始化一个运算符栈;

从左到右读取字符串;

左括号(入栈;1

字符串为运算符时:2

运算符栈为空则入栈;

该运算符优先级高于栈顶运算符时,入栈;否则弹出栈顶运算符写入后缀表达式然后该运算符入栈(栈顶运算优先级小于入栈的运算符);

字符是右括号)时,反复抛出栈顶元素入后缀表达式,直到栈顶为左括号,然后扔掉左括号和右括号。3

若读取完毕则将栈中的运算符送往后缀表达式。4

表达式中的优先级为:

_______________________________________

—  () —  +- — */% — ^    ——

—————————————————————————

—  0  —  1  — 2  —  3   —

_______________________________________

代码:

public String TransAf(String x)throws Exception{

Linkstack st=new Linkstack();//初始化运算符栈

String postString=new String();//初始化String类用于存放转换后的后缀表达式

for(int i=0;x!=null&&i

char c=x.charAt(i);//获取中缀表达式中当前的字符

/*********分四种情况将操作符入栈**********/

if(' '!=c)

{//判断该操作符不是结尾

if(isopenOperator(c))

{//该操作符是左括号则入栈1

st.push(c);

}//open

else if(iscloseOperator(c))

{//此时操作符为右括号2

Character ac=(Character) st.pop();//运算符栈做出栈操作

while(!isopenOperator(c))

{//不为左括号时则加到后缀表达式中

postString=postString.concat(String.valueOf(ac));

ac=(Character)st.pop();

}

}else if(isOperator(c))

{//此时为运算符3

if(!st.isEmpty())

{//若运算符栈不为空,弹出栈顶元素做优先级比较

Character  ac=(Character)st.pop();

while(ac != null&&priority(ac.charValue())>=priority(c)){//栈顶元素优先级高,则出栈操作

postString=postString.concat(String.valueOf(ac));//把栈抛出的元素加到后缀表达式中

ac=(Character)st.pop();//继续做出栈操作

}

if(ac!=null)

{//如果不满足while,即抛出的运算符优先级低于此时的运算符,

st.push(ac);//先把最后一次抛出的运算符入栈

}

}//if(!st.isEmpty()){

st.push(c);//然后把遍历的该运算符入栈

}

else{//遍历的符号为操作数,则直接加到后缀表达式中4

postString=postString.concat(String.valueOf(c));

}//4中情况分析完毕

}//if(' '!=c)

}//for

while(!st.isEmpty())//若中缀表达式以遍历完,此时操作符栈依然不为空

postString=postString.concat(String.valueOf(st.pop()));//直接把栈中的元素一次出栈加到后缀表达式中

return postString;//返回后缀表达式

}

/****************************对后缀表达式进行计算**********************************/

public double numCalculate(String postString)throws Exception{

Linkstack st=new Linkstack();

for(int i=0;postString!=null&&i

{

char c=postString.charAt(i);

if(isOperator(c))//判断每个字符是否是运算符

{

double d2=Double.valueOf(st.pop().toString());

double d1=Double.valueOf(st.pop().toString());

double d3=0;

if('+'==c)//判断是哪种运算符并进行计算

{

d3=d1+d2;

}else if('-'==c)

{

d3=d1-d2;

}else if('*'==c)

{

d3=d1*d2;

}else if('/'==c)

{

d3=d1/d2;

}else if('^'==c)

{

d3=Math.pow(d1, d2);

}else if('%'==c)

{

d3=d1%d2;

}

st.push(d3);//将计算后的结果入栈

}else//如果postString中的字符不是运算符,则执行入栈操作

{

st.push(c);

}

}

return (Double) st.pop();//最终,遍历完后缀表达式,在栈中取出最终的计算结果

}

/*********************判断字符是否是运算符*************************/

public boolean isOperator(char c){

if('+'==c||'-'==c||'*'==c||'/'==c||'^'==c||'%'==c)

return true;

else

return false;

}

/*********************判断字符是否是左括号*************************/

public boolean isopenOperator(char c){

return '('==c;

}

/*********************判断字符是否是右括号*************************/

public boolean iscloseOperator(char c){

return ')'==c;

}

/*********************判断字符的优先级*************************/

public int priority(char c){

if(c=='^')

return 3;

else if(c=='*'||c=='/'||c=='%')

return 2;

else if(c=='+'||c=='-')

return 1;

else

return 0;

}

主函数:

public static void main(String[] args)throws Exception{

CountB  con=new CountB();

String postString=con.TransAf("(1+2)*(5-2)/2^2+5%3");

System.out.println("表达式的结果为:"+con.numCalculate(postString));

}

注:表达式一般有中缀表达式、后缀表达式和前缀表达式3种表示形式。

中缀表达式是将运算符放在两个操作数的中间;

后缀表达式将运算符放在两个操作数之后;

前缀表达式是将操作符放在两个操作数之前。

后缀表达式中既无操作符的优先级又无括号的约束问题,英雌可以按后缀表达式中运算符出现的顺序进行计算求值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值