Loading

计算包含+、-、*、/、(、)等几种运算符的表达式的值。

package com.math;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;

/**
 * 表达式求值
 */
public class Calculator {

    private static final int MAXCAPACITY = 500;
    private String expression;

    public Calculator(String expression) {
        if (expression.length() > MAXCAPACITY)
            System.out.println("字符串长度超出最大值");
        else
            this.expression = expression;
    }

    public int getPriority(String str) {
        int pri = -1;

        if (str.equals("("))
            pri = 0;
        else if (str.equals("+") || str.equals("-"))
            pri = 1;
        else if (str.equals("*") || str.equals("/"))
            pri = 2;

        return pri;
    }

    public String[] split() {
        ArrayList<String> strList = new ArrayList<String>();
        int splitIndex = 0;

        for (int i = 0; i < expression.length(); i++) {
            if (expression.charAt(i) == '+' || expression.charAt(i) == '-' || expression.charAt(i) == '*' || expression.charAt(i) == '/' || expression.charAt(i) == '(' || expression.charAt(i) == ')') {
                if (splitIndex == i) { //处理连续多个操作符
                    if (expression.charAt(i) == '-') {     //处理操作符"( + - * /"符号后面遇到"-"情况时,将后面的数字当做负数处理
                        splitIndex = i;
                        continue;
                    } else
                        strList.add(expression.substring(splitIndex, i + 1));
                } else {
                    strList.add(expression.substring(splitIndex, i));
                    strList.add(expression.substring(i, i + 1));
                }
                splitIndex = i + 1;
            }
            if ((i == expression.length() - 1) && (splitIndex <= i))
                strList.add(expression.substring(splitIndex));
        }

        return strList.toArray(new String[0]);
    }

    public String[] getSuffixExpression(String[] expression) {
        Stack<String> strStack = new Stack<String>();
        ArrayList<String> strList = new ArrayList<String>();

        for (int i = 0; i < expression.length; i++) {
            if (expression[i].equals("("))  //遇到'('时入栈
                strStack.push(expression[i]);
            else if (expression[i].equals("+") || expression[i].equals("-") || expression[i].equals("*") || expression[i].equals("/")) {
                if (strStack.isEmpty())     //栈空时操作符入栈
                    strStack.push(expression[i]);
                else {                     //否则比较栈顶操作符优先级
                    while ((!strStack.isEmpty()) && (getPriority(strStack.peek()) >= getPriority(expression[i]))) {
                        strList.add(strStack.pop());
                    }
                    strStack.push(expression[i]);
                }
            } else if (expression[i].equals(")")) {//遇到')'时出栈直至'('
                while (!strStack.peek().equals("(")) {
                    strList.add(strStack.pop());
                }
                strStack.pop(); //抛出'('
            } else
                strList.add(expression[i]);
        }
        while (!strStack.isEmpty())
            strList.add(strStack.pop());

        return strList.toArray(new String[0]);
    }

    public double getResult(String[] expression) {
        Stack<Double> strStack = new Stack<Double>();
        double num1, num2;
        double result = 0;

        for (int i = 0; i < expression.length; i++) {
            if (expression[i].equals("+") || expression[i].equals("-") || expression[i].equals("*") || expression[i].equals("/")) {
                String str = expression[i];
                switch (str) {
                    case "+": {
                        num1 = strStack.pop();
                        num2 = strStack.pop();
                        //BigDcimal的作用:解决计算过程中丢失精度问题
                        result = (BigDecimal.valueOf(num1).add(BigDecimal.valueOf(num2))).doubleValue();
                        strStack.push(result);
                        break;
                    }
                    case "-": {
                        num1 = strStack.pop();
                        num2 = strStack.pop();
                        result = (BigDecimal.valueOf(num2).subtract(BigDecimal.valueOf(num1))).doubleValue();
                        strStack.push(result);
                        break;
                    }
                    case "*": {
                        num1 = strStack.pop();
                        num2 = strStack.pop();
                        result = num2 * num1;
                        result = (BigDecimal.valueOf(num2).multiply(BigDecimal.valueOf(num1))).doubleValue();
                        strStack.push(result);
                        break;
                    }
                    case "/": {
                        num1 = strStack.pop();
                        num2 = strStack.pop();
                        result = (BigDecimal.valueOf(num2).divide(BigDecimal.valueOf(num1))).doubleValue();
                        strStack.push(result);
                        break;
                    }
                }
            } else
                strStack.push(Double.valueOf(expression[i]));
        }

        result = 0;
        while (!strStack.isEmpty()) {
            result += strStack.pop();
        }

        return result;
    }

    public double getResult() {
        return getResult(getSuffixExpression(split()));
    }

    /**
     * 计算包含+、-、*、/、(、)等几种运算符的表达式的值。
     */
    public static void main(String[] args) {
        try {  //第一步:输入包含表达式的字符串
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入表达式并以#结束:");
            //第二步:计算表达式的值
            StringBuffer sb = new StringBuffer();
            while (true) {
                String s = scanner.next();
                sb.append(s);
                if (sb.toString().endsWith("#")) {
                    break;
                }
                if (sb.toString().equals("#")) {
                    System.out.println("请输入表达式");
                }
            }
            String line = sb.toString().substring(0, sb.toString().length() - 1);
            //第三步:输出计算结果
            Calculator exp1 = new Calculator(line);
            String[] strSplit = exp1.split();
            String[] strSuffixExpression = exp1.getSuffixExpression(strSplit);
            double result = exp1.getResult(strSuffixExpression);
            System.out.println("计算结果:" + line + "=" + result);
        } catch (Exception e) {
            System.err.println("请输入合法的表达式!");
        }

    }
}

 

posted @ 2022-02-20 16:19  Roc-xb  阅读(57)  评论(0)    收藏  举报

易微帮源码


易微帮官网