Есть ли в Java функция eval ()?

java eval

147454 просмотра

12 ответа

2218 Репутация автора

У меня есть строка, подобная следующей:

String str = "4*5";

Теперь я должен получить результат 20, используя строку.

Я знаю, что на некоторых других языках eval()функция сделает это. Как я могу сделать это на Java?

Автор: karthi_ms Источник Размещён: 09.04.2010 04:07

Ответы (12)


5 плюса

102085 Репутация автора

Нет , вы не можете иметь универсальный «eval» в Java (или любой другой скомпилированный язык). Если вы не хотите писать компилятор Java и JVM для выполнения внутри вашей Java-программы .

Да , вы можете иметь некоторую библиотеку для оценки числовых алгебраических выражений, подобных приведенному выше - смотрите эту тему для обсуждения .

Автор: DVK Размещён: 09.04.2010 04:16

141 плюса

37127 Репутация автора

Решение

Вы можете использовать ScriptEngineкласс и оценивать его как строку Javascript.

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

Может быть, есть и лучший способ, но этот работает.

Автор: Jeff Storey Размещён: 09.04.2010 04:16

44 плюса

555356 Репутация автора

Не существует стандартного Java-класса или метода, который будет делать то, что вы хотите. Ваши варианты включают в себя:

  • Выберите и используйте какую-нибудь стороннюю библиотеку для оценки выражений. Например, JEL или любая из полдюжины библиотек, перечисленных здесь .

  • Оберните выражение в исходном коде Java для класса с помощью evalметода, отправьте его компилятору Java, а затем загрузите полученный скомпилированный класс.

  • Используйте некоторый язык сценариев, который может быть вызван из Java в качестве оценщика выражений. Возможности включают в себя Javascript, BeanShell и так далее.

  • Написать свой собственный оценщик выражений с нуля.

Первый подход, вероятно, самый простой. Второй и третий подходы представляют потенциальную угрозу безопасности, если вы получаете выражение, которое будет оценено ненадежным пользователем. (Подумайте о внедрении кода.)

Автор: Stephen C Размещён: 09.04.2010 04:16

0 плюса

300199 Репутация автора

Нет ничего, что будет делать это в JavaSE; вам придется искать сторонние библиотеки или писать свои собственные.

Автор: polygenelubricants Размещён: 09.04.2010 04:17

7 плюса

4582 Репутация автора

Как и в предыдущих ответах, в Java нет стандартного API для этого.

Вы можете добавить файлы groovy jar к своему пути, и groovy.util.Eval.me ("4 * 5") выполнит вашу работу.

Автор: Adi Размещён: 09.04.2010 05:55

3 плюса

1351 Репутация автора

Написание вашей собственной библиотеки не так сложно, как вы думаете. Вот ссылка на алгоритм Маневрового двора с пошаговым описанием алгоритма. Хотя сначала вам придется проанализировать входные данные для токенов.

Есть еще 2 вопроса, которые также могут дать вам некоторую информацию: Превратить строку в математическое выражение? Что такое хорошая библиотека для разбора математических выражений в Java?

Автор: Srneczek Размещён: 22.10.2013 07:20

30 плюса

29155 Репутация автора

Существует очень мало реальных случаев использования, в которых возможность или оценка Stringфрагмента кода Java необходима или желательна. То есть вопрос о том, как это сделать, действительно является проблемой XY : на самом деле у вас другая проблема, которую можно решить другим способом.

Сначала спросите себя, откуда это Stringто, что вы хотите оценить? Была ли другая часть вашей программы сгенерирована или введена пользователем?

  • Его сгенерировала другая часть моей программы : так, вы хотите, чтобы одна часть вашей программы определяла тип выполняемой операции, но не выполнение операции, и вторая часть, которая выполняет выбранную операцию. Вместо того, чтобы генерировать и затем оценивать String, используйте шаблон проектирования « Стратегия» , « Команда» или « Строитель» , соответствующий вашему конкретному случаю.

  • Это пользовательский ввод : пользователь может вводить все , что угодно , включая команды, которые при выполнении могут привести к неправильной работе вашей программы, аварийному завершению, раскрытию информации, которая должна быть секретной, повреждению постоянной информации (такой как содержимое базы данных) и другим подобным гадость. Единственный способ предотвратить это - проанализировать Stringсебя, убедиться, что он не является вредоносным, а затем оценить его. Но сам синтаксический анализ - это большая часть работы, которую выполняет запрашиваемая evalфункция, поэтому вы ничего не сэкономили. Что еще хуже, проверить, что произвольное Javaне было вредоносным, невозможно , потому что проверка - это проблема остановки .

  • Это пользовательский ввод, но синтаксис и семантика разрешенного текста для оценки сильно ограничены : никакое средство общего назначения не может легко реализовать синтаксический анализатор и анализатор общего назначения для любого ограниченного синтаксиса и семантики, которые вы выбрали. Что вам нужно сделать, это реализовать анализатор и оценщик для выбранного вами синтаксиса и семантики. Если задача проста, вы можете написать простой парсер рекурсивного спуска или конечного автомата вручную. Если задача сложная, вы можете использовать компилятор-компилятор (такой как ANTLR), чтобы выполнить часть работы за вас.

  • Я просто хочу реализовать настольный калькулятор! : Домашнее задание, а? Если бы вы могли реализовать оценку входного выражения, используя предоставленную evalфункцию, это не было бы большим домашним заданием, не так ли? Ваша программа будет длиной в три строки. Ваш инструктор, вероятно, ожидает от вас написания кода для простого арифметического анализатора / оценщика. Существует хорошо известный алгоритм, шунтирующий двор , который может оказаться полезным.

Автор: Raedwald Размещён: 10.12.2014 08:31

12 плюса

462 Репутация автора

Я мог бы посоветовать вам использовать Exp4j . Это легко понять, как видно из следующего примера кода:

Expression e = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
    .variables("x", "y")
    .build()
    .setVariable("x", 2.3)
    .setVariable("y", 3.14);
double result = e.evaluate();
Автор: chAlexey Размещён: 20.04.2015 11:16

4 плюса

96 Репутация автора

Интересным способом решения вашей проблемы может быть кодирование функции eval () самостоятельно! Я сделал это для тебя!

Вы можете использовать библиотеку FunctionSolver, просто набрав FunctionSolver.solveByX ( function , value ) внутри своего кода. Функция атрибута является строка , которая представляет собой функцию , которую нужно решить, то значение атрибута является значение независимой переменной вашей функции (которая должна быть х).

Если вы хотите решить функцию, которая содержит более одной независимой переменной, вы можете использовать FunctionSolver.solve ( функция , значения ), где атрибут values - это HashMap (String, Double), который содержит все ваши независимые атрибуты (как строки) и их соответствующие значения (как Doubles).

Еще одна информация: я написал простую версию FunctionSolver , поэтому она поддерживает только методы Math, которые возвращают двойное значение и которые принимают одно или два двойных значения в качестве полей (просто используйте FunctionSolver.usableMathMethods (), если вам интересно) (Эти методы: bs, sin, cos, tan, atan2, sqrt, log, log10, pow, exp, min, max, copySign, signum, IEEEremainder, acos, asin, atan, cbrt, ceil, cosh, expm1, floor , hypot, log1p, nextAfter, nextDown, nextUp, random, rint, sinh, tanh, toDegrees, toRadians, ulp) . Кроме того, эта библиотека поддерживает следующие операторы: * / + - ^ (даже если Java обычно не поддерживает оператор ^).

И последнее: при создании этой библиотеки мне пришлось использовать отражения для вызова математических методов . Я думаю, что это действительно круто, просто посмотрите на это, если вам интересно!

Вот и все, вот код (и библиотека ):

package core;

 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;

 public abstract class FunctionSolver {

public static double solveNumericExpression (String expression) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    return solve(expression, new HashMap<>());
}

public static double solveByX (String function, double value) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

    HashMap<String, Double> values = new HashMap<>();
    values.put("x", value);
    return solveComplexFunction(function, function, values);
}

public static double solve (String function, HashMap<String,Double> values) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

    return solveComplexFunction(function, function, values);
}

private static double solveComplexFunction (String function, String motherFunction, HashMap<String, Double> values) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

    int position = 0;
    while(position < function.length()) {
        if (alphabetic.contains(""+function.charAt(position))) {
            if (position == 0 || !alphabetic.contains(""+function.charAt(position-1))) {
                int endIndex = -1;
                for (int j = position ; j < function.length()-1 ; j++) {
                    if (alphabetic.contains(""+function.charAt(j)) 
                            && !alphabetic.contains(""+function.charAt(j+1))) {
                        endIndex = j;
                        break;
                    }
                }
                if (endIndex == -1 & alphabetic.contains(""+function.charAt(function.length()-1))) {
                    endIndex = function.length()-1;
                }
                if (endIndex != -1) {
                    String alphabeticElement = function.substring(position, endIndex+1);
                    if (Arrays.asList(usableMathMethods()).contains(alphabeticElement)) {
                        //Start analyzing a Math function
                        int closeParenthesisIndex = -1;
                        int openedParenthesisquantity = 0;
                        int commaIndex = -1;
                        for (int j = endIndex+1 ; j < function.length() ; j++) {
                            if (function.substring(j,j+1).equals("(")) {
                                openedParenthesisquantity++;
                            }else if (function.substring(j,j+1).equals(")")) {
                                openedParenthesisquantity--;
                                if (openedParenthesisquantity == 0) {
                                    closeParenthesisIndex = j;
                                    break;
                                }
                            }else if (function.substring(j,j+1).equals(",") & openedParenthesisquantity == 0) {
                                if (commaIndex == -1) {
                                    commaIndex = j;
                                }else{
                                    throw new IllegalArgumentException("The argument of math function (which is "+alphabeticElement+") has too many commas");
                                }
                            }
                        }
                        if (closeParenthesisIndex == -1) {
                            throw new IllegalArgumentException("The argument of a Math function (which is "+alphabeticElement+") hasn't got the closing bracket )");
                        }   
                        String functionArgument = function.substring(endIndex+2,closeParenthesisIndex);
                        if (commaIndex != -1) {
                            double firstParameter = solveComplexFunction(functionArgument.substring(0,commaIndex),motherFunction,values);
                            double secondParameter = solveComplexFunction(functionArgument.substring(commaIndex+1),motherFunction,values);
                            Method mathMethod = Math.class.getDeclaredMethod(alphabeticElement, new Class<?>[] {double.class, double.class});
                            mathMethod.setAccessible(true);
                            String newKey = getNewKey(values);
                            values.put(newKey, (Double) mathMethod.invoke(null, firstParameter, secondParameter));
                            function = function.substring(0, position)+newKey
                                       +((closeParenthesisIndex == function.length()-1)?(""):(function.substring(closeParenthesisIndex+1)));
                        }else {
                            double firstParameter = solveComplexFunction(functionArgument, motherFunction, values);
                            Method mathMethod = Math.class.getDeclaredMethod(alphabeticElement, new Class<?>[] {double.class});
                            mathMethod.setAccessible(true);
                            String newKey = getNewKey(values);
                            values.put(newKey, (Double) mathMethod.invoke(null, firstParameter));
                            function = function.substring(0, position)+newKey
                                       +((closeParenthesisIndex == function.length()-1)?(""):(function.substring(closeParenthesisIndex+1)));
                        }   
                    }else if (!values.containsKey(alphabeticElement)) {
                        throw new IllegalArgumentException("Found a group of letters ("+alphabeticElement+") which is neither a variable nor a Math function: ");
                    }
                }
            }
        }
        position++;
    }
    return solveBracketsFunction(function,motherFunction,values);
}

private static double solveBracketsFunction (String function,String motherFunction,HashMap<String, Double> values) throws IllegalArgumentException{

    function = function.replace(" ", "");
    String openingBrackets = "([{";
    String closingBrackets = ")]}";
    int parenthesisIndex = 0;
    do {
        int position = 0;
        int openParenthesisBlockIndex = -1;
        String currentOpeningBracket = openingBrackets.charAt(parenthesisIndex)+"";
        String currentClosingBracket = closingBrackets.charAt(parenthesisIndex)+"";
        if (contOccouranceIn(currentOpeningBracket,function) != contOccouranceIn(currentClosingBracket,function)) {
            throw new IllegalArgumentException("Error: brackets are misused in the function "+function);
        }
        while (position < function.length()) {
            if (function.substring(position,position+1).equals(currentOpeningBracket)) {
                if (position != 0 && !operators.contains(function.substring(position-1,position))) {
                    throw new IllegalArgumentException("Error in function: there must be an operator following a "+currentClosingBracket+" breacket");
                }
                openParenthesisBlockIndex = position;
            }else if (function.substring(position,position+1).equals(currentClosingBracket)) {
                if (position != function.length()-1 && !operators.contains(function.substring(position+1,position+2))) {
                    throw new IllegalArgumentException("Error in function: there must be an operator before a "+currentClosingBracket+" breacket");
                }
                String newKey = getNewKey(values);
                values.put(newKey, solveBracketsFunction(function.substring(openParenthesisBlockIndex+1,position),motherFunction, values));
                function = function.substring(0,openParenthesisBlockIndex)+newKey
                           +((position == function.length()-1)?(""):(function.substring(position+1)));
                position = -1;
            }
            position++;
        }
        parenthesisIndex++;
    }while (parenthesisIndex < openingBrackets.length());
    return solveBasicFunction(function,motherFunction, values);
}

private static double solveBasicFunction (String function, String motherFunction, HashMap<String, Double> values) throws IllegalArgumentException{

    if (!firstContainsOnlySecond(function, alphanumeric+operators)) {
        throw new IllegalArgumentException("The function "+function+" is not a basic function");
    }
    if (function.contains("**") |
        function.contains("//") |
        function.contains("--") |
        function.contains("+*") |
        function.contains("+/") |
        function.contains("-*") |
        function.contains("-/")) {
        /*
         * ( -+ , +- , *- , *+ , /- , /+ )> Those values are admitted
         */
        throw new IllegalArgumentException("Operators are misused in the function");
    }
    function = function.replace(" ", "");
    int position;
    int operatorIndex = 0;
    String currentOperator;
    do {
        currentOperator = operators.substring(operatorIndex,operatorIndex+1);
        if (currentOperator.equals("*")) {
            currentOperator+="/";
            operatorIndex++;
        }else if (currentOperator.equals("+")) {
            currentOperator+="-";
            operatorIndex++;
        }
        operatorIndex++;
        position = 0;
        while (position < function.length()) {
            if ((position == 0 && !(""+function.charAt(position)).equals("-") && !(""+function.charAt(position)).equals("+") && operators.contains(""+function.charAt(position))) ||
                (position == function.length()-1 && operators.contains(""+function.charAt(position)))){
                throw new IllegalArgumentException("Operators are misused in the function");
            }
            if (currentOperator.contains(function.substring(position, position+1)) & position != 0) {
                int firstTermBeginIndex = position;
                while (firstTermBeginIndex > 0) {
                    if ((alphanumeric.contains(""+function.charAt(firstTermBeginIndex))) & (operators.contains(""+function.charAt(firstTermBeginIndex-1)))){
                        break;
                    }
                    firstTermBeginIndex--;
                }
                if (firstTermBeginIndex != 0 && (function.charAt(firstTermBeginIndex-1) == '-' | function.charAt(firstTermBeginIndex-1) == '+')) {
                    if (firstTermBeginIndex == 1) {
                        firstTermBeginIndex--;
                    }else if (operators.contains(""+(function.charAt(firstTermBeginIndex-2)))){
                        firstTermBeginIndex--;
                    }
                }
                String firstTerm = function.substring(firstTermBeginIndex,position);
                int secondTermLastIndex = position;
                while (secondTermLastIndex < function.length()-1) {
                    if ((alphanumeric.contains(""+function.charAt(secondTermLastIndex))) & (operators.contains(""+function.charAt(secondTermLastIndex+1)))) {
                        break;
                    }
                    secondTermLastIndex++;
                }
                String secondTerm = function.substring(position+1,secondTermLastIndex+1);
                double result;
                switch (function.substring(position,position+1)) {
                    case "*": result = solveSingleValue(firstTerm,values)*solveSingleValue(secondTerm,values); break;
                    case "/": result = solveSingleValue(firstTerm,values)/solveSingleValue(secondTerm,values); break;
                    case "+": result = solveSingleValue(firstTerm,values)+solveSingleValue(secondTerm,values); break;
                    case "-": result = solveSingleValue(firstTerm,values)-solveSingleValue(secondTerm,values); break;
                    case "^": result = Math.pow(solveSingleValue(firstTerm,values),solveSingleValue(secondTerm,values)); break;
                    default: throw new IllegalArgumentException("Unknown operator: "+currentOperator);
                }
                String newAttribute = getNewKey(values);
                values.put(newAttribute, result);
                function = function.substring(0,firstTermBeginIndex)+newAttribute+function.substring(secondTermLastIndex+1,function.length());
                deleteValueIfPossible(firstTerm, values, motherFunction);
                deleteValueIfPossible(secondTerm, values, motherFunction);
                position = -1;
            }
            position++;
        }
    }while (operatorIndex < operators.length());
    return solveSingleValue(function, values);
}

private static double solveSingleValue (String singleValue, HashMap<String, Double> values) throws IllegalArgumentException{

    if (isDouble(singleValue)) {
        return Double.parseDouble(singleValue);
    }else if (firstContainsOnlySecond(singleValue, alphabetic)){
        return getValueFromVariable(singleValue, values);
    }else if (firstContainsOnlySecond(singleValue, alphanumeric+"-+")) {
        String[] composition = splitByLettersAndNumbers(singleValue);
        if (composition.length != 2) {
            throw new IllegalArgumentException("Wrong expression: "+singleValue);
        }else {
            if (composition[0].equals("-")) {
                composition[0] = "-1";
            }else if (composition[1].equals("-")) {
                composition[1] = "-1";
            }else if (composition[0].equals("+")) {
                composition[0] = "+1";
            }else if (composition[1].equals("+")) {
                composition[1] = "+1";
            }
            if (isDouble(composition[0])) {
                return Double.parseDouble(composition[0])*getValueFromVariable(composition[1], values);
            }else if (isDouble(composition[1])){
                return Double.parseDouble(composition[1])*getValueFromVariable(composition[0], values);
            }else {
                throw new IllegalArgumentException("Wrong expression: "+singleValue);
            }
        }
    }else {
        throw new IllegalArgumentException("Wrong expression: "+singleValue);
    }
}

private static double getValueFromVariable (String variable, HashMap<String, Double> values) throws IllegalArgumentException{

    Double val = values.get(variable);
    if (val == null) {
        throw new IllegalArgumentException("Unknown variable: "+variable);
    }else {
        return val;
    }
}

/*
 * FunctionSolver help tools:
 * 
 */

private static final String alphabetic = "abcdefghilmnopqrstuvzwykxy";
private static final String numeric = "0123456789.";
private static final String alphanumeric = alphabetic+numeric;
private static final String operators = "^*/+-"; //--> Operators order in important!

private static boolean firstContainsOnlySecond(String firstString, String secondString) {

    for (int j = 0 ; j < firstString.length() ; j++) {
        if (!secondString.contains(firstString.substring(j, j+1))) {
            return false;
        }
    }
    return true;
}

private static String getNewKey (HashMap<String, Double> hashMap) {

    String alpha = "abcdefghilmnopqrstuvzyjkx";
    for (int j = 0 ; j < alpha.length() ; j++) {
        String k = alpha.substring(j,j+1);
        if (!hashMap.containsKey(k) & !Arrays.asList(usableMathMethods()).contains(k)) {
            return k;
        }
    }
    for (int j = 0 ; j < alpha.length() ; j++) {
        for (int i = 0 ; i < alpha.length() ; i++) {
            String k = alpha.substring(j,j+1)+alpha.substring(i,i+1);
            if (!hashMap.containsKey(k) & !Arrays.asList(usableMathMethods()).contains(k)) {
                return k;
            }
        }
    }
    throw new NullPointerException();
}

public static String[] usableMathMethods () {

    /*
     *  Only methods that:
     *  return a double type
     *  present one or two parameters (which are double type)
     */

    Method[] mathMethods = Math.class.getDeclaredMethods();
    ArrayList<String> usableMethodsNames = new ArrayList<>();
    for (Method method : mathMethods) {
        boolean usable = true;
        int argumentsCounter = 0;
        Class<?>[] methodParametersTypes = method.getParameterTypes();
        for (Class<?> parameter : methodParametersTypes) {
            if (!parameter.getSimpleName().equalsIgnoreCase("double")) {
                usable = false;
                break;
            }else {
                argumentsCounter++;
            }
        }
        if (!method.getReturnType().getSimpleName().toLowerCase().equals("double")) {
            usable = false;
        }
        if (usable & argumentsCounter<=2) {
            usableMethodsNames.add(method.getName());
        }
    }
    return usableMethodsNames.toArray(new String[usableMethodsNames.size()]);
}

private static boolean isDouble (String number) {
    try {
        Double.parseDouble(number);
        return true;
    }catch (Exception ex) {
        return false;
    }
}

private static String[] splitByLettersAndNumbers (String val) {
    if (!firstContainsOnlySecond(val, alphanumeric+"+-")) {
        throw new IllegalArgumentException("Wrong passed value: <<"+val+">>");
    }
    ArrayList<String> response = new ArrayList<>();
    String searchingFor;
    int lastIndex = 0;
    if (firstContainsOnlySecond(""+val.charAt(0), numeric+"+-")) {
        searchingFor = alphabetic;
    }else {
        searchingFor = numeric+"+-";
    }
    for (int j = 0 ; j < val.length() ; j++) {
        if (searchingFor.contains(val.charAt(j)+"")) {
            response.add(val.substring(lastIndex, j));
            lastIndex = j;
            if (searchingFor.equals(numeric+"+-")) {
                searchingFor = alphabetic;
            }else {
                searchingFor = numeric+"+-";
            }
        }
    }
    response.add(val.substring(lastIndex,val.length()));
    return response.toArray(new String[response.size()]);
}

private static void deleteValueIfPossible (String val, HashMap<String, Double> values, String function) {
    if (values.get(val) != null & function != null) {
        if (!function.contains(val)) {
            values.remove(val);
        }
    }
}

private static int contOccouranceIn (String howManyOfThatString, String inThatString) {
    return inThatString.length() - inThatString.replace(howManyOfThatString, "").length();
}
 }
Автор: Vinciuz Размещён: 14.01.2018 03:58

1 плюс

92 Репутация автора

Поскольку есть много ответов, я добавляю свою реализацию поверх eval()метода с некоторыми дополнительными функциями, такими как поддержка факториала, оценка сложных выражений и т. Д.

package evaluation;

import java.math.BigInteger;
import java.util.EmptyStackException;
import java.util.Scanner;
import java.util.Stack;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class EvalPlus {
    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.println("This Evaluation is based on BODMAS rule\n");
        evaluate();
    }

    private static void evaluate() {
        StringBuilder finalStr = new StringBuilder();
        System.out.println("Enter an expression to evaluate:");
        String expr = scanner.nextLine(); 
        if(isProperExpression(expr)) {
            expr = replaceBefore(expr);
            char[] temp = expr.toCharArray();
            String operators = "(+-*/%)";
            for(int i = 0; i < temp.length; i++) {
                if((i == 0 && temp[i] != '*') || (i == temp.length-1 && temp[i] != '*' && temp[i] != '!')) {
                    finalStr.append(temp[i]);
                } else if((i > 0 && i < temp.length -1) || (i==temp.length-1 && temp[i] == '!')) {
                    if(temp[i] == '!') {
                        StringBuilder str = new StringBuilder();
                        for(int k = i-1; k >= 0; k--) {
                            if(Character.isDigit(temp[k])) {
                                str.insert(0, temp[k] );
                            } else {
                                break;
                            }
                        }
                        Long prev = Long.valueOf(str.toString());
                        BigInteger val = new BigInteger("1");
                        for(Long j = prev; j > 1; j--) {
                            val = val.multiply(BigInteger.valueOf(j));
                        }
                        finalStr.setLength(finalStr.length() - str.length());
                        finalStr.append("(" + val + ")");
                        if(temp.length > i+1) {
                            char next = temp[i+1];
                            if(operators.indexOf(next) == -1) { 
                                finalStr.append("*");
                            }
                        }
                    } else {
                        finalStr.append(temp[i]);
                    }
                }
            }
            expr = finalStr.toString();
            if(expr != null && !expr.isEmpty()) {
                ScriptEngineManager mgr = new ScriptEngineManager();
                ScriptEngine engine = mgr.getEngineByName("JavaScript");
                try {
                    System.out.println("Result: " + engine.eval(expr));
                    evaluate();
                } catch (ScriptException e) {
                    System.out.println(e.getMessage());
                }
            } else {
                System.out.println("Please give an expression");
                evaluate();
            }
        } else {
            System.out.println("Not a valid expression");
            evaluate();
        }
    }

    private static String replaceBefore(String expr) {
        expr = expr.replace("(", "*(");
        expr = expr.replace("+*", "+").replace("-*", "-").replace("**", "*").replace("/*", "/").replace("%*", "%");
        return expr;
    }

    private static boolean isProperExpression(String expr) {
        expr = expr.replaceAll("[^()]", "");
        char[] arr = expr.toCharArray();
        Stack<Character> stack = new Stack<Character>();
        int i =0;
        while(i < arr.length) {
            try {
                if(arr[i] == '(') {
                    stack.push(arr[i]);
                } else {
                    stack.pop();
                }
            } catch (EmptyStackException e) {
                stack.push(arr[i]);
            }
            i++;
        }
        return stack.isEmpty();
    }
}

Пожалуйста, найдите обновленную суть в любое время здесь . Также прокомментируйте, если есть какие-либо проблемы. Благодарю.

Автор: abubakkar Размещён: 11.07.2018 10:09

10 плюса

15615 Репутация автора

С Java 9 мы получаем доступ jshell, поэтому можно написать что-то вроде этого:

import jdk.jshell.JShell;
import java.lang.StringBuilder;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Eval {
    public static void main(String[] args) throws IOException {
        try(JShell js = JShell.create(); BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {

            js.onSnippetEvent(snip -> {
                if (snip.status() == jdk.jshell.Snippet.Status.VALID) {
                    System.out.println("➜ " + snip.value());
                }
            });

            System.out.print("> ");
            for (String line = br.readLine(); line != null; line = br.readLine()) {
                js.eval(js.sourceCodeAnalysis().analyzeCompletion(line).source());
                System.out.print("> ");
            }
        }
    }
}

Образец прогона:

> 1 + 2 / 4 * 3
➜ 1
> 32 * 121
➜ 3872
> 4 * 5
➜ 20
> 121 * 51
➜ 6171
>

Немного оп, но это то, что Java в настоящее время может предложить

Автор: smac89 Размещён: 27.09.2018 03:31

0 плюса

1 Репутация автора

Следующее решило проблему:

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String str = "4*5";
System.out.println(engine.eval(str));
Автор: jaya swamy Размещён: 26.09.2019 08:28
Вопросы из категории :
32x32