Java表达式求值(前缀、中缀、后缀)

表达式求值需要利用进行计算

  1. 前缀表达式: 又称波兰表达式,由右向左遍历表达式,遇到数字就压入栈,遇到运算符就连续弹出两个栈顶元素,用【第一个栈顶元素,运算符,第二个栈顶元素】计算新值压入栈。
  2. 后缀表达式: 又称逆波兰表达式,由左向右遍历表达式,遇到数字就压入栈,遇到运算符就连续弹出两个栈顶元素,用【第二个栈顶元素,运算符,第一个栈顶元素】计算新值压入栈。
  3. 中缀表达式: 中缀表达式要记录运算符,遇到一个"(“,就要找到所有该括号中的表达式,递归遍历。有左向右遍历表达式,初始化运算符为”+":
    • 如果是数字,检测下一个字符是否为数字,如果是就与当前字符拼接,如果不是,根据运算符压入新的值。(如果操作符是"-"就要压入负值)
    • 如果是"(",就递归遍历。
    • 如果是运算符,就更新运算符的值。
public class Test {
    public static void main(String[] args){
        String preOrder = "+3*2+1*2+/(-4)-867";
        String inOrder = "3+2*(1+2*(-4/(8-6)+7))";
        String postOrder = "3212(-4)86-/7+*+*+";

        Test t = new Test();
        System.out.println("前缀表达式(波兰表达式)的计算结果是:"+t.preExpression(preOrder));
        System.out.println("中缀表达式的计算结果是:"+t.inExpression(inOrder));
        System.out.println("后缀表达式(逆波兰表达式)的计算结果是:"+t.postExpression(postOrder));
    }
    public int preExpression(String expression){
        //由右向左遍历,将数字压入栈,遇到运算符就连续弹出两个栈顶元素进行运算
        Deque<Integer> stack = new ArrayDeque<>();
        for(int i=expression.length()-1;i>=0;i--){
            char c = expression.charAt(i);
            if(c==')'){
                int j=i;
                while (expression.charAt(i)!='('){
                    i--;
                }
                int tmp = Integer.parseInt(expression.substring(i+1,j));
                stack.push(tmp);
            }else if(c>='0' && c<='9'){
                int tmp = Integer.parseInt(String.valueOf(c));
                stack.push(tmp);
            }else if(c == '+'){
                int a = stack.pop();
                int b = stack.pop();
                stack.push(a+b);
            }else if(c == '-'){
                int a = stack.pop();
                int b = stack.pop();
                stack.push(a-b);
            }else if(c == '*'){
                int a = stack.pop();
                int b = stack.pop();
                stack.push(a*b);
            }
            else if(c == '/'){
                int a = stack.pop();
                int b = stack.pop();
                stack.push(a/b);
            }
        }


        return stack.pop();
    }
    public void convertNum(int num,Deque<Character> opStack,Deque<Integer> numStack){
        char op = opStack.pop();
        if(op=='+') numStack.push(num);
        else if(op=='-') numStack.push(-num);
        else if(op=='/') numStack.push(numStack.pop()/num);
        else if(op=='*') numStack.push(numStack.pop()*num);
    }
    public void convertNum(int num,char op,Deque<Integer> numStack){
        if(op=='+') numStack.push(num);
        else if(op=='-') numStack.push(-num);
        else if(op=='/') numStack.push(numStack.pop()/num);
        else if(op=='*') numStack.push(numStack.pop()*num);
    }
    public int inExpression(String expression){
        //中缀相对于前后缀,多了对括号的处理,括号的优先级最高,然后是*/,最后是+-
        //由于可能出现负值,所以遇到减号,就将其与后面数字一起加入数字栈,将减法看作加法
        Deque<Integer> numStack = new ArrayDeque<>();
        char op = '+';
        for(int i=0;i<expression.length();i++){
            char c = expression.charAt(i);
            if(Character.isDigit(c)){
                int num = 0;
                while(i<expression.length() && Character.isDigit(expression.charAt(i))){
                    num = num * 10+expression.charAt(i)-'0';
                    i++;
                }
                convertNum(num,op,numStack);
                i--;
            }else if(c == '('){
                //记录(的个数
                int count = 1;
                int j = i+1;
                while(j<expression.length() && count>0){
                    if(expression.charAt(j) == '(') count++;
                    else if(expression.charAt(j) == ')') count--;
                    j++;
                }
                int num = inExpression(expression.substring(i+1,j-1));
                convertNum(num,op,numStack);
                i = j-1;
            }else{
                op = c;
            }
        }
        int ans = 0;
        while(!numStack.isEmpty()) ans+=numStack.pop();

        return ans;
    }
    public int postExpression(String expression){
        //由左向右遍历,将数字压入栈,遇到运算符就连续弹出两个栈顶元素进行运算
        Deque<Integer> stack = new ArrayDeque<>();
        for(int i=0;i<expression.length();i++){
            char c = expression.charAt(i);
            if(c == '('){
                int j = i;
                while (expression.charAt(i)!=')'){
                    i++;
                }
                int tmp = Integer.parseInt(expression.substring(j+1,i));
                stack.push(tmp);
            }else if(c>='0' && c<='9') {
                int tmp = Integer.parseInt(String.valueOf(c));
                stack.push(tmp);
            }else if(c == '+'){
                int a = stack.pop();
                int b = stack.pop();
                stack.push(b+a);
            }else if(c == '-'){
                int a = stack.pop();
                int b = stack.pop();
                stack.push(b-a);
            }else if(c == '*'){
                int a = stack.pop();
                int b = stack.pop();
                stack.push(b*a);
            }
            else if(c == '/'){
                int a = stack.pop();
                int b = stack.pop();
                stack.push(b/a);
            }
        }
        return stack.pop();
    }
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值