0

我将此作为服务器响应:

"[(sin(1+3*4)+2)/7]+10"

此响应意味着 1、3、4、2、7 和 10 是 DB(mysql)上的某种索引项,我需要对其进行多次评估。我在 java 中寻找一个好的库,我发现 exp4j、expr、jep 和 jeval 就像数学表达式解析器一样,但我看不到在哪里获取这些“索引”的选项,因为服务器只给了我那个字符串但是不要给我需要在我的数据库中查阅的“索引项”。请帮忙 :(

额外:1、3、4、2、7 和 10 是变量,我需要获取它(不总是数字),因为这些变量名称是我在数据库中的索引。当我得到名称时,我创建一个 sql 查询来获取该变量的实际值。

就像这样...

ParseMath function = new ParseMath("[(sin(1+3*4)+2)/7]+10");
String[] variables = function.getVariables();

System.out.println(values) = 1, 3, 4, 2, 7, 10

然后...

String[] realValues = SqlQuery(variables);

for(int i=0; i<variables.lenght(); i++){
function.setValue(variable[i],realValue[i]);
}

double result = function.exec();

PS:我写的函数和方法不存在,我只是把它当作我的问题的上下文......

4

2 回答 2

2

大多数表达式解析器会将数字视为数字。如果您希望它们被视为变量,请用字母替换或前缀它们,即执行以下操作:

ParseMath function = new ParseMath(replaceVariables("[(sin(1+3*4)+2)/7]+10"));

其中 replaceVariables 将是这样的:

String replaceVariables(String expr) {
  StringBuilder sb = new StringBuilder();
  boolean wasDigit = false;
  for (int i = 0; i < expr.length; i++) {
    char c = sb.charAt(i);
    if (c >= '0' && c <= '9') {
      if (!wasDigit) {
        sb.append('x');
      }
      wasDigit = true;
    } else if (c == '[') {
      c = '(';
    } else if (c == ']') {
      c = ')';
    }
    sb.append(c);
  }
  return sb.toString();
}

这应该将示例表达式转换((sin(x1+x3*x4)+x2)/x7)+x10为更容易被表达式解析器识别的表达式。

请注意,当您设置变量时,您需要进行相同的转换,即如果您的服务器响应在 String 数组realValues中,您需要执行与此类似的操作来设置它们:

for (int i = 0; i < realValues.length; i++) {
  function.setValue("x" + i, Double.parseDouble(realValues[i]));
}
double result = function.exec();
于 2012-06-20T21:56:31.503 回答
0

我对我的正则表达式有点生疏,但我认为这是最有效的方法。正则表达式将为您提供表达式中变量和数字的名称,然后您可以使用表达式库为您提供的任何工具来替换值。请注意,您需要知道服务器可以返回的每个函数,以便您可以从您的结果中排除它们(它们看起来像变量)。

public static void main( String[] args ) {
    String expression = "[(sin(1+3*4)+2)/7]+10";
    LinkedList<String> vars = new LinkedList<>();

    Pattern p = Pattern.compile("(?:[^0-9a-zA-Z]|\\G|^)([0-9a-zA-Z]+)(?:[^0-9a-zA-Z]|$)");
    Matcher m = p.matcher( expression );

    while(m.find()) {
        vars.add( m.group( 1 ) );
    }

    for(String s : vars ) {
        // Here's where you'd filter out the functions like "sin", "cos", etc.
        System.out.println( s );
    }
}

我建议您使用一些示例对其进行测试,以确保我的正则表达式中没有任何漏洞。

于 2012-06-20T22:09:31.440 回答