Como analisar uma expressão matemática dado como uma string e retornar um número? [duplicado]

StackOverflow https://stackoverflow.com/questions/1432245

Pergunta

Esta questão já tem uma resposta aqui:

Existe uma maneira em Java para obter o resultado desta expressão matemática:

String code = "5+4*(7-15)";

No outro lado, qual é a melhor maneira de analisar uma expressão aritmética?

Foi útil?

Solução

Você pode passá-lo para um BeanShell bsh.Interpreter, algo como isto:

Interpreter interpreter = new Interpreter();
interpreter.eval("result = 5+4*(7-15)");
System.out.println(interpreter.get("result"));

Você vai querer garantir a cadeia que avaliar é de uma fonte confiável e as precauções normais, mas caso contrário ele vai trabalhar fora em linha reta.

Se você quiser ir um mais complicado (mas mais seguro) se aproximar de você poderia usar ANTLR (que eu suspeito tem uma gramática matemática como um ponto de partida) e realmente compilar / interpretar a declaração si mesmo.

Outras dicas

i recentemente desenvolveu um analisador de expressão e lançado sob a licença Apache. você pode agarrá-lo em http://projects.congrace.de/exp4j/index.html

esperança que ajudou

Você pode usar a classe ScriptEngine e avaliá-lo como uma string javascript

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");        
Object result = engine.eval("5+4*(7-15)");

Na verdade, yu deve saber que o resultado do seguinte instrução em javascript:

   eval('var aa=5+4*(7-15)')
   aa // -27

Pode haver uma maneira melhor, mas este funciona.

Provavelmente não tão simples de uma maneira que você está esperando!

Mas talvez você poderia usar um javax.script.ScriptEngine e tratar a string como uma expressão ECMAScript, por exemplo?

Dê uma olhada em: Scripting para o Plataforma Java.

Não há nenhuma maneira builtin de fazer isso. Mas você pode usar um dos muitos muitos open source calculadoras disponíveis.

Recentemente eu estava usando muito maduro matemática biblioteca de analisador de expressão, de código aberto, dando a mesma API para Java e .NET. O nome da biblioteca é mXparser. mXparser fornece funcionalidades básicas (fórmulas simples análise e de cálculo) e outras mais avançadas (ou seja definido de utilizador argumentos, funções). Além disso, vale a pena notar que mXparser tem rica coleção interna de matemática (ou seja, operadores, / binários / funções variádicos unários, reiterou operadoras como a soma e produto).

http://mathparser.org/

http://mathparser.org/mxparser-tutorial/

Veja abaixo alguns exemplos de ter visão mais clara sobre a sintaxe.

Exemplo 1 - fórmula simples

Expression e = new Expression("2+3");
double v = e.calculate();

Exemplo 2 - embutido função

Expression e = new Expression("2+sin(3)");
double v = e.calculate();

Exemplo 3 - constantes incorporados

Expression e = new Expression("2+sin(pi)");
double v = e.calculate();

Exemplo 4 - definido de utilizador argumentos e constantes

Argument x = new Argument("x = 5");
Constant a = new Constant("a = 2 + sin(3)");
Expression e = new Expression("a + x^2", x, a);
double v1 = e.calculate();
x.setArgumentValue(10);
double v2 = e.calculate();

Exemplo 5 - funções definidas pelo utilizador

Function f = new Function("f(x,y) = x^2 + cos(y)");
Expression e = new Expression("f(10,pi) - 3", f);
double v = e.calculate();

Exemplo 6 - utilizador recursão definido

Function factorial = new Function("fact(n) = if( n > 0; n*fact(n-1); 1)");
Expression e = new Expression("fact(10) - 10!", factorial);
double v = e.calculate();

Encontrado recntly - no caso de você gostaria de tentar a sintaxe (e ver o caso de uso avançado), você pode baixar o aplicativo Scalar Calculator que é alimentado por mXparser.

Com os melhores cumprimentos

LK

Não há suporte direto no Java SDK para fazer isso.

Você terá que implementá-lo (possivelmente usando um gerador de analisador como JavaCC), ou use uma biblioteca existente.

Uma opção seria JEP (comercial), outro JEval (software livre).

Há uma ferramenta comercial chamado formula4j que faz esse trabalho.

Para tomar o seu exemplo expressão, seria avaliada como esta usando formula4j:

Formula formula = new Formula("5+4*(7-15)");

Decimal answer = formula.getAnswer(); //-27

Você coul usar esse projeto

Como usar:

double result = 0;
String code = "5+4*(7-15)";
try {
    Expr expr = Parser.parse(code);
    result = expr.value();
} catch (SyntaxException e) {
    e.printStackTrace();
}
System.out.println(String.format("Result: %.04f", result));
public static int calc(String string){
    int result=0; 
    String numbers="0123456789";
    String operations="+-/*";
    for (int i=0;i<string.length();i++){
        if (numbers.contains(string.charAt(i)+"")){
            result=result*10+(Integer.parseInt(string.charAt(i)+""));
            }
        else {
            if (string.charAt(i)=='+'){ result+=calc(string.substring(i+1));}
            if (string.charAt(i)=='-'){ result-=calc(string.substring(i+1));}
            if (string.charAt(i)=='*'){ result*=calc(string.substring(i+1));}
            if (string.charAt(i)=='/'){ try{result/=calc(string.substring(i+1));}
                catch (ArithmeticException e){
                    System.err.println("You cannot devide by Zero!");}
            }  
            break;
        }        
    }
    return result;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top