【问题标题】:evaluating expressions containing functions in java在java中评估包含函数的表达式
【发布时间】:2014-12-05 15:28:29
【问题描述】:

我编写了一个项目,它可以在不使用 java 中的 math 等现有包的情况下计算正弦、MCM 等不同的函数 现在我想从用户那里得到一个字符串形式的表达式,然后打印出结果
喜欢:

import java.util.Scanner;

public class Phase2main {

public static void main(String[] args) {

    Scanner s = new Scanner(System.in);
    String expression   ;
    double result = 0 ;

    System.out.println(" Enter your desired expression from the available functions ");

    expression = s.nextLine();


    System.out.println("Result is : " + result);                
 }
}

那么它应该像这样运行: 输入表达式:ADD(DIV(SIN(FACT(3)),CEIL(TAN(MUL(1.5,FIB(4))))),GCD(2,10)) 结果是:1.94

如何让程序识别我的功能,如 CEIL 及其输入? 我检查了许多类似的问题,但我发现的那些是相当复杂的库,我无法理解或在没有识别函数及其输入的情况下进行基本算术运算

那么我怎样才能为这个特定问题编写一个简单的评估器呢?

【问题讨论】:

  • 您可以使用OGNL 实现此目的。它很容易使用。您可以创建一个上下文并使用它来评估表达式。
  • 这是一个非常广泛的问题。如果您只想识别函数 - 使用任何解析器(或编写自己的 - 那里有大量指南)。如果您也需要评估方面的帮助 - 那么这个问题类似于“帮助我编写自己的 Wolfram Alpha!”
  • 除非您找到符合您需要的语法的库,否则没有简单的解决方案可以解决您的问题。您必须借助 javacc、antlr 或 eclipse Xtext 等解析器生成器编写自己的解析器。
  • 你能推荐一个简单的库吗?我看过这个github.com/uklimaschewski/EvalEx,但我不明白如何将我的结果和输入与该库联系起来
  • JavaCC : cs.rit.edu/~ats/java/html/skript/4__04.htmld 或 XText zverovich.net/2011/12/03/first-experience-with-xtext.html。您也可以阅读此stackoverflow.com/questions/7258538/…。但恐怕这个解决方案都不是你所说的“简单库”。

标签: java expression evaluator


【解决方案1】:

可以使用 JavaScript 解释器吗?

首先创建引擎实例并初始化:

// Manager creates engines by mime/language names.
// It has own global scope for engiges created by it.
ScriptEngineManager manager = new ScriptEngineManager();
// Create JavaScript interpreter instance.
// (Nashorn is bundled JavaScript interpreter)
ScriptEngine scope = manager.getEngineByName("JavaScript");
// Define functions you need
String initialScript = "cos = Math.cos;" // ; or \n
    + "sin = Math.sin;"
    + "tg  = Math.tan;"
    + "PI  = Math.PI;"
// Any other function
    + "ctg = function (x) { return cos(x)/sin(x); };";
// ...

try {
    // Add these functions to scope
    scope.eval(initialScript);
} catch(ScriptException ex) {
    // Evaluating exceptions, syntax errors are thrown here
}

然后你可以多次评估“范围”内的表达式:

try {
    double d = (double)scope.eval("sin(PI/2) + cos(PI/2)");
    System.out.println("Calculated: " + d);
} catch(ScriptException e) {
    // ...
}

请注意:

  1. 有语言解释 - 用户可以传递任何脚本和...
  2. ...它会降低应用程序的性能。

例如,您还可以使用JythonJRuby 作为解释器。

【讨论】:

  • 什么是范围?使用未定义类型时出现编译错误
  • 再次感谢我仍然无法对您的解决方案做的事情是我想从用户那里获取表达式作为字符串然后将结果打印出来我也没有使用数学包。我我正在使用我为 sin cos 和其他人编写的函数,我还应该在这里更改什么? paste.ubuntu.com/9387085
  • 您可以定义完全自己的函数和常量,如上所示。嗯,什么是 COS.calcuCOS 等,它在哪里定义的?
  • 我已经定义了cos。 calcuCOS 在另一个类中,它工作正常
  • 这是项目的第二阶段。第一阶段是制作一个计算所有java函数的程序。 lang math 包不使用包本身(通过使用泰勒级数和其他方式)第二阶段是编写一个程序,接收由阶段1函数组成的字符串形式的表达式并打印结果
【解决方案2】:

您可以使用Java Scripting API, and for instance use JavaScript, or BeanShell (java like).

    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByMimeType("text/javascript");
    try {
        engine.eval("print('Result: ' + java.lang.Math.sin(0.8))");
        double y = ((Number) engine.eval("java.lang.Math.sin(0.8)")).doubleValue();
    } catch (ScriptException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    }

JavaScript 可以使用导入。可以看到,调用java非常简单。

【讨论】:

    【解决方案3】:

    我不确定是否有任何简单的方法可以在不使用库的情况下识别和评估通用输入表达式。

    如果您想开发自己的方法来评估数学表达式,请查看此页面,它应该会告诉您要走的路:http://cogitolearning.co.uk/?p=565

    如果您改变主意并想使用图书馆,请查看此链接:Evaluating a math expression given in string form

    我在构建 java 编译器时已经这样做了,这样我就可以读取和评估任何表达式,但这并不简单......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-14
      • 2016-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多