后缀表达式的计算器Java实现

直接上代码

package cn.john.cal;

/**
 * 
 * @ClassName: Operators
 * 
 * @Description: 操作符枚举
 * 
 * @author: John
 * 
 * @date: 2017年5月9日 下午22:05:16
 * 
 * 
 */
public enum OperatorsEnum {

    PLUS(0, '+'), MINUS(0, '-'), MULTIPLY(1, '*'), DIVIDE(1, '/'), MODULAR(1, '%'), LEFT_BRACKET(2,
            '('), RIGHT_BRACKET(2, ')');

    public Integer prior;// 优先级
    public Character operator;// 操作符

    private OperatorsEnum(int prior, char operator) {
        this.prior = prior;
        this.operator = operator;
    }

    public String toString() {
        return String.valueOf(operator);
    }

}
package cn.john.cal;

import java.util.LinkedList;
import java.util.Scanner;

/**
 * 
 * @ClassName: Cal
 * 
 * @Description:
 *               <p>
 *               基于后缀表达式的简易计算器,目前支持个位数加、减、乘、除、模和括号六种运算。
 *               <p>
 *               中缀表达式->后缀表达式 操作符入栈
 *               <p>
 *               后缀表达式->计算值 操作数入栈
 * 
 * @author: John
 * 
 * @date: 2017年5月9日 下午7:55:58
 * 
 */
public class Cal {

    /**

     * @Title: toPostFix

     * @Description: 将中缀表达式转换为后缀表达式

     * @param infix
     * @return

     * @return: String

     */
    public String toPostFix(String infix) {
        // 算式字符数组
        char[] ch = infix.trim().toCharArray();
        LinkedList<OperatorsEnum> stack = new LinkedList<OperatorsEnum>();
        StringBuilder sb = new StringBuilder();

        OperatorsEnum op = null;

        for (int i = 0; i < ch.length; i++) {
            // 对每个算式字符,检查它是不是操作符
            if ((op = isOperator(ch[i])) == null) {
                sb.append(ch[i]);
            } else {
                // 右括号
                // 持续弹出栈顶元素直到遇到左括号,但是不输出左括号
                if (op.equals(OperatorsEnum.RIGHT_BRACKET)) {
                    // 如果不是左括号,持续弹出并输出
                    while (!stack.peek().equals(OperatorsEnum.LEFT_BRACKET)) {
                        sb.append(stack.pop());
                    }
                    // 此时栈顶元素为左括号,直接弹出,不输出
                    stack.pop();
                } else {
                    // 非右括号
                    // 1、弹出并输出所有高优先级或者同等优先级,直到遇到低优先级或者左括号为止
                    // 上面的弹出语句有可能将栈弹空,检查stack的size避免NPE
                    while (stack.size() > 0 && stack.peek().prior >= op.prior
                            && !stack.peek().equals(OperatorsEnum.LEFT_BRACKET)) {
                        sb.append(stack.pop());
                    }
                    // 2、将当前操作符入栈
                    stack.push(op);
                }
            }
        }
        // 弹出所有栈中剩余操作符
        while (stack.size() > 0) {
            sb.append(stack.pop());
        }

        return sb.toString();
    }

    /**

     * @Title: calc

     * @Description: 计算后缀表达式的值

     * @param postfix
     * @return

     * @return: double

     */
    public double calc(String postfix) {
        char[] ch = postfix.toCharArray();
        LinkedList<Double> stack = new LinkedList<Double>();
        OperatorsEnum op = null;
        for (int i = 0; i < ch.length; i++) {
            if ((op = isOperator(ch[i])) == null) {
                // 不是操作符,将当前数值入栈
                stack.push(Double.parseDouble(String.valueOf(ch[i])));
            } else {
                // 是操作符,进行计算
                double b = stack.pop();
                double a = stack.pop();
                switch (op) {
                case PLUS:
                    stack.push(a + b);
                    break;
                case MINUS:
                    stack.push(a - b);
                    break;
                case MULTIPLY:
                    stack.push(a * b);
                    break;
                case DIVIDE:
                    stack.push(a / b);
                    break;
                case MODULAR:
                    stack.push(a % b);
                    break;
                default:
                    break;
                }
            }
        }
        return stack.pop();
    }

    /**

     * @Title: isOperator

     * @Description: 判断字符是否为操作符

     * @param ch
     * @return

     * @return: OperatorsEnum

     */
    private OperatorsEnum isOperator(char ch) {
        for (OperatorsEnum op : OperatorsEnum.values()) {
            if (ch == op.operator) {
                return op;
            }
        }
        return null;
    }


    // test

    /**

     * @Title: readEquation

     * @Description: 终端输入算式

     * @return

     * @return: String

     */
    public String readEquation() {
        Scanner sc = new Scanner(System.in);
        String equation = sc.nextLine();
        sc.close();
        return equation;
    }

    public static void main(String[] args) {
        Cal c = new Cal();
        System.out.println("Please input an equation,press ENTER to submit!");
        String infix = c.readEquation();
        String s = c.toPostFix(infix);
        System.out.println("postfix: " + s);
        System.out.println("Result: "+infix + "=" + c.calc(s));
    }
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值