表达式求值

1. 后序(逆波兰)

对形如 ABC*+ 的后序表达式进行求值,所有操作数均为 0 - 9 的整数,操作符包含 +、-、*、/ ,其中 +、- 均为二元操作符

import java.util.Stack;

/**
 * 后序表达式求值
 */
public class PostfixSolution {
    private Stack<Integer> result = new Stack<>();

    private void calculate(char operator) {
        int right = result.pop();
        int left = result.pop();

        switch (operator) {
            case '+':
                result.push(left + right);
                break;
            case '-':
                result.push(left - right);
                break;
            case '*':
                result.push(left * right);
                break;
            case '/':
                result.push(left / right);
                break;
            default:
                System.exit(1);
                break;
        }
    }

    public int solve(String postfix) {
        char[] array = postfix.toCharArray();

        for (int i = 0; i < array.length; i++) {
            if (Character.isDigit(array[i])) {
                result.push(array[i] - '0');
            } else {
                calculate(array[i]);
            }
        }

        return result.pop();
    }

    public static void main(String[] args) {
        System.out.println(new PostfixSolution().solve("32+"));
    }
}

2. 中序

中序表达式求值一般可以分为两步,

  • 中序表达式转后序
  • 后序求值

两步合并为一步操作如下:

import java.util.Stack;

/**
 * 中缀表达式(含括号)求值
 */
public class InfixSolution {

    private static Stack<Integer> result = new Stack<>();
    private static Stack<Character> operator = new Stack<>();

    private static void calculate(char operator) {
        int right = result.pop();
        int left = result.pop();

        switch (operator) {
            case '+':
                result.push(left + right);
                break;
            case '-':
                result.push(left - right);
                break;
            case '*':
                result.push(left * right);
                break;
            case '/':
                result.push(left / right);
                break;
            default:
                System.exit(1);
                break;
        }
    }

    private static int getPriority(char operator) {
        if (operator == '#') {
            return 0;
        } else if (operator == '('){
            return 1;
        } else if (operator == '+' || operator == '-') {
            return 2;
        } else if (operator == '*' || operator == '/') {
            return 3;
        } else {
            return -1;
        }
    }

    /**
     * 一般操作顺序:
     * 1. 中序 ---> 后序
     * 2. 后序求值
     * 现将两步合并为一步
     * 使用两个栈,分别为最终结果栈 result 与操作符栈 operator,operator 预置优先级最低的 '#'
     * 循环遍历中序序列,遇操作数入 result;
     * 遇操作符:
     * 1. '(': 直接入 operator
     * 2. ')': operator 不断退栈并利用该元素计算
     * 3. '+、-、*、/': 与 operator 栈顶元素比较,
     * 若当前优先级<=栈顶运算符的优先级,则不断退栈并利用该元素计算;
     * 否则入 operator
     */
    private static void solve(String infix) {
        char[] array = infix.toCharArray();
        for (int i = 0; i < array.length; i++) {
            if (Character.isDigit(array[i])) { // 操作数
                result.push(array[i] - '0');
            } else {
                if (array[i] == '(') {
                    operator.push(array[i]);
                } else if (array[i] == ')') {
                    char temp = operator.pop();
                    for (; temp != '('; temp = operator.pop()) {
                        calculate(temp);
                    }
                } else if (getPriority(array[i]) <= getPriority(operator.peek())) {
                    char temp = operator.peek();

                    while (getPriority(array[i]) <= getPriority(temp)) {
                        calculate(temp);
                        operator.pop();
                        temp = operator.peek();
                    }
                } else {
                    operator.push(array[i]);
                }
            }
        }

        if (operator.peek() != '#') {
            calculate(operator.pop());
        }

        System.out.println(result.pop());
    }

    public static void main(String[] args) {
        operator.push('#');

        solve("(2+3)*(8-2)");
    }
}

3. 前序(波兰)

import java.util.Stack;

/**
 * 前序表达式求值
 */
public class PrefixSolution {

    private Stack<Integer> result = new Stack<>();

    /**
     * 由于逆向扫描表达式,所以先退栈的是第一个操作数
     */
    private void calculate(char operator) {
        int left = result.pop();
        int right = result.pop();

        switch (operator) {
            case '+':
                result.push(left + right);
                break;
            case '-':
                result.push(left - right);
                break;
            case '*':
                result.push(left * right);
                break;
            case '/':
                result.push(left / right);
                break;
            default:
                System.exit(1);
                break;
        }
    }

    /**
     * 扫描从右往左进行
     * 遇操作数,入 result
     * 遇操作符,从 result 弹出两个操作数进行计算
     * 扫描结束后,result 栈顶就是表达式结果
     */
    private int solve(String prefix) {
        char[] array = prefix.toCharArray();

        for (int i = array.length - 1; i >= 0; i--) {
            if (Character.isDigit(array[i])) {
                result.push(array[i] - '0');
            } else {
                calculate(array[i]);
            }
        }

        return result.pop();
    }

    public static void main(String[] args) {
        System.out.println(new PrefixSolution().solve("-32"));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值