【问题标题】:Turn a String into a Math Expression? [duplicate]将字符串转换为数学表达式? [复制]
【发布时间】:2013-02-11 15:50:26
【问题描述】:

假设我有一个这样声明的方法:

public double Calc(String expression) {

// Code

}

我想采用类似的字符串表达式

"2 + 4 - (3 * 4)"

然后将它提供给Calc(),它应该返回它得到的值。

你能从一个字符串中解析出一个数学表达式,让它变成一个Java可以理解的表达式吗?因为通常你可以写

return 2 + 4 - (3 * 4);

但这仅适用于单个表达式。

【问题讨论】:

  • 要自己滚动,您通常会使用表达式树en.wikipedia.org/wiki/Binary_expression_tree
  • @beto 但似乎这样做,你打开整个 JS 引擎只是为了做这件事。虽然它给了我一个暗示,我想。谢谢!
  • 用正则表达式来简化解决方案,使用BODMAS原理并执行语句。您可以使用循环遍历表达式。评估每个条件,最后抛出答案。 JS 方法不好,因为注入是对您的应用程序的真正威胁。
  • 谷歌“评估中缀表达式”,你会找到答案。

标签: java parsing math


【解决方案1】:

让我声明一个可以采用的过程作为答案,因为我认为通过浏览关于 SO 的几个问题,您应该对如何在不加载 JS 编译器的情况下执行此操作有一个公平的想法。

对于初学者,您需要通过将数学字符串转换为中缀字符串的函数来解析字符串。然后,您基本上通过在循环中分解字符串以返回您的答案来将此表达式评估为另一个函数。精美详细的流程可以found here

【讨论】:

    【解决方案2】:

    我建议使用 Dijkstra 的 twostack 算法。

    这应该是你所需要的:

    public class DijkstraTwoStack {
        public static void main(String[] args) {
                    Scanner scanner = new Scanner(System.in);
                    String exp[] = scanner.nextLine().split(" ");
            Stack<String> ops = new Stack<String>();
            Stack<Double> vals = new Stack<Double>();
    
            for(int i = 0; i < exp.length; i++) {
                            String s = exp[i];
                if (s.equals("(")) {
                }
                else if (s.equals("+") || s.equals("*")) {
                    ops.push(s);
                } else if (s.equals(")")) {
                    getComp(ops, vals);
                } else {
                    vals.push(Double.parseDouble(s));
                }
            }
            getComp(ops, vals);
            System.out.println(vals.pop());
        }
    
        private static void getComp(Stack<String> ops, Stack<Double> vals) {
            String op = ops.pop();
            if (op.equals("+")) {
                vals.push(vals.pop() + vals.pop());
            } else if (op.equals("*")) {
                vals.push(vals.pop() * vals.pop());
            }
        }
    }
    

    没测试过,应该差不多吧。

    【讨论】:

    • 效率不高,但可以使用它....ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("js"); Object result = engine.eval("3+4"); *credits : stackoverflow.com/a/2605051/936786
    • 请不要更改现有答案的代码。不需要迭代器,它会破坏算法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2020-12-15
    • 1970-01-01
    相关资源
    最近更新 更多