首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 計算字符串數學表達式:JDK 1.5 無內置函數,需實現後綴表達式解析器

     編輯:程式設計綜合問答

JDK 1.5 (及所有標準版) 無內置 API 直接計算 "3*5+5" 這類字符串表達式。需自行實現或引入第三方庫。

核心算法:中綴轉後綴 (逆波蘭表達式) + 棧計算

  1. 詞法分析:將字符串拆分為 Token (數字、運算符、括號)。
  2. 中綴轉後綴 (Shunting-yard 算法):運算符優先級 * / > + -,左結合。
  3. 後綴求值:遇數字入棧,遇運算符彈出兩數計算結果入棧。

簡易實現 (支援 + - * / ( ))

import java.util.*;

public class ExprEval {
    public static double eval(String expr) {
        List postfix = toPostfix(tokenize(expr));
        return calcPostfix(postfix);
    }

    static List tokenize(String s) {
        List tokens = new ArrayList<>();
        StringBuilder num = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isDigit(c) || c == '.') num.append(c);
            else {
                if (num.length() > 0) { tokens.add(num.toString()); num.setLength(0); }
                if (c != ' ') tokens.add(String.valueOf(c));
            }
        }
        if (num.length() > 0) tokens.add(num.toString());
        return tokens;
    }

    static List toPostfix(List tokens) {
        List out = new ArrayList<>();
        Deque op = new ArrayDeque<>();
        for (String t : tokens) {
            if (isNumber(t)) out.add(t);
            else if (t.equals("(")) op.push(t);
            else if (t.equals(")")) {
                while (!op.peek().equals("(")) out.add(op.pop());
                op.pop();
            } else { // operator
                while (!op.isEmpty() && !op.peek().equals("(") && prec(op.peek()) >= prec(t))
                    out.add(op.pop());
                op.push(t);
            }
        }
        while (!op.isEmpty()) out.add(op.pop());
        return out;
    }

    static int prec(String op) {
        return (op.equals("*") || op.equals("/")) ? 2 : 1;
    }

    static boolean isNumber(String s) {
        try { Double.parseDouble(s); return true; } catch { return false; }
    }

    static double calcPostfix(List postfix) {
        Deque st = new ArrayDeque<>();
        for (String t : postfix) {
            if (isNumber(t)) st.push(Double.parseDouble(t));
            else {
                double b = st.pop(), a = st.pop();
                switch (t) {
                    case "+": st.push(a + b); break;
                    case "-": st.push(a - b); break;
                    case "*": st.push(a * b); break;
                    case "/": st.push(a / b); break;
                }
            }
        }
        return st.pop();
    }

    public static void main(String[] args) {
        System.out.println(eval("3*5+5")); // 20.0
    }
}

成熟第三方庫 (推薦生產環境)

  • exp4j:new ExpressionBuilder("3*5+5").build().evaluate(),輕量、快、支援變量/函數。
  • JEP (Java Expression Parser):功能豐富、商業友好。
  • MVEL:強大表達式語言、整合 Spring。

Maven 依賴示例

<dependency>
    <groupId>net.objecthunter</groupId>
    <artifactId>exp4j</artifactId>
    <version>0.4.8</version>
</dependency>

不要重複造輪子,生產環境直接用 exp4j 等成熟庫;教學/面試可手寫 Shunting-yard 算法展示功力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved