括号表达式 java_java中栈的应用-带括号的算术表达式

问题分析:

表达式有中缀表达式,后缀表达式和前缀表达式;

其中中缀表达式就是我们平常写的算术表达式,而后缀表达式就是将运算符放在两个操作数之后,前缀则放在之前;

例如:中缀表达式:A+(B-C/D)*E  对应的后缀表达式就是 ABCD/-E*+,前缀类比

由于后缀表达式中无运算优先级又无括号的约束问题,因此计算一个后缀表达式比计算一个中缀表达式咬简单

1将原算术表达式转换成后缀表达式

要使运算符出现的次序与真正的算术顺序一致,就要使优先数高的以及括号内的运算符先出现在前,所以需要一个栈来保留未被送到后缀表达式的运算符

算法思路如下:

(1)初始化一个运算符栈

(2)从算术表达式输入的字符串中从左到右读取一个字符

(3)若字符使操作数,则直接送往后缀表达式

(4)若当前字符是左括号,则压进栈内

(5)若当前字符为运算符,则进行下面操作:

(5.1)当运算符为空时,则将其压入栈中

(5.2)当此运算符优先级高于栈顶字符,则将其压入栈中;否则,去出栈中字符送到后缀表达式,并将当前运算符压栈

(6)若当前字符为右括号,则反复将栈顶弹出送往后缀表达式,直到栈顶为左括号为止,再将左括号丢弃

(7)若读取还未完毕,则转到步骤2

(8)若读取结束,则将栈中的运算符弹出并送往后缀表达式

2计算后缀表达式

问题分析:

要计算后缀表达式的值比较简单,只要先找到运算符,在去找之前最后两个操作数;

利用一个栈来保留后缀表达式中还未参加运算的操作数,称为操作数栈

算法分析如下:

1.初始化一个操作数栈

2从左到右依次读入后缀表达式的字符

(1)若当前为操作数,则将操作数压入栈中

(2)若当前为运算符,则从栈顶弹出两个操作数参与运算,并将运算结果压入操作栈中

3重复步骤2直到后缀表达式为空为止,则操作栈中的栈顶元素即为后缀表达式的计算结果

import java.util.Stack;

public class Example3_3 {

//将算术表达式转换为后缀表达式的函数,结果一字符串的形式返回

public String converToPostfix(String expression)throws Exception{

Stack st=new Stack<>(); //初始化一个运算符栈

String postfix=new String(); //用于储存后缀表达式

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

char c=expression.charAt(i);

if(' '!=c){

//为左括号

if(isOpenParent(c)){

st.push(c);

}//为右括号

else if(isCloseParent(c)){

char ac=st.pop();

while(!isOpenParent(ac)){

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

ac=st.pop();

}

}//为运算符

else if(isOperator(c)){

//运算栈非空,取出栈顶优先级高的运算符送完后缀表达式

if(!st.empty()){

char ac=st.pop();

//栈取出的字符优先级比c高

while(!st.isEmpty()&&priority(ac)>=priority(c)){

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

ac=st.pop();

}//栈取出的字符优先级比c低,则将取出的字符重新入栈

if(ac!=' '){

st.push(ac);

}

}st.push(c); //将c入栈

}//为操作数,直接串联到postfix内

else {

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

}

}

}//当表达式读完就将算术栈pop出加入postfix

while(!st.isEmpty()){

postfix=postfix.concat(String.valueOf(st.pop()));

}

return postfix;

}

//对后缀表达式进行运算的函数

public double numberCalculate(String postfix)throws Exception{

Stack st=new Stack<>();//创建一个操作数栈

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

char c=postfix.charAt(i);

//如果为运算符

if(isOperator(c)&&!st.isEmpty()){

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

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

double d3=0;

if('+'==c){

d3=d1+d2;

}

if('-'==c){

d3=d1-d2;

}

if('/'==c){

d3=d1/d2;

}

if('*'==c){

d3=d1*d2;

}

if('%'==c){

d3=d1%d2;

}

if('^'==c){

d3=Math.pow(d1, d2);

}

//将运算结果压入操作数栈中

st.push(d3);

}else{//为操作数时直接压入操作数栈

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 isOpenParent(char c){

return c=='(';

}

//判断字符为右括号

public boolean isCloseParent(char c){

return c==')';

}

//判断算法的优先级

public int priority(char c){

if(c=='^'){

return 3;

}

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

return 2;

}

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

return 1;

}

else return 0;

}

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

// TODO Auto-generated method stub

Example3_3 p=new Example3_3();

String postfix =p.converToPostfix("3+2*8+(5+5)+2^2/2*5%3");

System.out.println("表达式结果为:"+p.numberCalculate(postfix));

}

}运算结果

表达式结果为:30.0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值