Java: проблема с регулярным выражением, попытка сопоставить алгебраический термин [duplicate]

Существует множество способов сделать это, и важно выбрать правильный. Вероятно, одним из самых больших архитектурных решений является то, как код модели будет доступен или доступен во всем приложении.

Я написал сообщение в блоге об этом некоторое время назад: Общий код модели , Ниже приведен краткий обзор:

Общие данные

. Один из подходов состоит в том, чтобы совместно использовать указатели на объекты модели между контроллерами представления.

  • Итерация с принудительной передачей на контроллерах представления (в навигаторе или панели управления панелью) для установки данных
  • Установите данные в файле подготовки (если раскадровки) или init (если программно)

Поскольку подготовка к segue является наиболее распространенной, здесь приведен пример:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    var next = segue.destinationViewController as NextViewController
    next.dataSource = dataSource
}

Независимый доступ

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

Наиболее распространенный способ, которым я видел это, - это экземпляр singleton . Поэтому, если ваш объект singleton был DataAccess, вы можете сделать следующее в методе viewDidLoad для UIViewController:

func viewDidLoad() {
    super.viewDidLoad()
    var data = dataAccess.requestData()
}

. Существуют дополнительные инструменты, которые также помогают передавать данные:

  • Замечание о ключевом значении
  • NSNotification
  • Основные данные
  • NSFetchedResultsController
  • Источник данных

] Основные данные

Хорошая вещь в Core Data заключается в том, что она имеет обратные отношения. Поэтому, если вы хотите просто предоставить NotesViewController объект заметок, который вы можете использовать, поскольку он будет иметь обратную связь с чем-то другим, например, с ноутбуком. Если вам нужны данные на ноутбуке в NotesViewController, вы можете вернуться к графику объекта, выполнив следующие действия:

let notebookName = note.notebook.name

Подробнее об этом читайте в моем сообщении в блоге: Общий код модели

262
задан Francesco Menzani 20 September 2015 в 14:17
поделиться

25 ответов

С JDK1.6 вы можете использовать встроенный механизм Javascript.

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

public class Test {
  public static void main(String[] args) throws ScriptException {
    ScriptEngineManager mgr = new ScriptEngineManager();
    ScriptEngine engine = mgr.getEngineByName("JavaScript");
    String foo = "40+2";
    System.out.println(engine.eval(foo));
    } 
}
320
ответ дан Abdull 26 August 2018 в 15:46
поделиться
public class StringCalculator {

    public static void main(String[] args) {

        String eval = "2+3*2/2+2*5/5*5";

        System.out.println(calculator(eval));
    }

    public static int calcMulAndDiv(String val){

        String nos[] = val.split("\\D+");
        String opr[] = val.split("\\d+");
        int res = Integer.parseInt(nos[0]);

        for(int i = 1; i< opr.length ;i++){

            if(opr[i].equals("*")){
                res = res * Integer.parseInt(nos[i]);
            }
            else if(opr[i].equals("/")){
                res = res / Integer.parseInt(nos[i]);
            }

        }

        return res;
    }

    public static int calculator(String val){

        String nos[] = val.split("[+-]");
        String operators = val.replaceAll("[^+-]","");
        char opr[] = operators.toCharArray();
        int result = 0;

        if(nos[0].contains("*") || nos[0].contains("*")){
            result = calcMulAndDiv(nos[0]);
        }else{
            result = Integer.parseInt(nos[0]);
        }

        for(int i = 0 ; i < opr.length ; i++){

            if(opr[i] == '+'){
                if(nos[i+1].contains("*") || nos[i+1].contains("*")){
                    result = result + calcMulAndDiv(nos[i+1]);
                }else{
                    result = result + Integer.parseInt(nos[i+1]);
                }
            }
            else if(opr[i] == '-'){
                if(nos[i+1].contains("*") || nos[i+1].contains("*")){
                    result = result + calcMulAndDiv(nos[i+1]);
                }else{
                    result = result - Integer.parseInt(nos[i+1]);
                }
            }

        }

        return result;
    }
}
-2
ответ дан Arpan 26 August 2018 в 15:46
поделиться

Я написал этот метод eval для арифметических выражений, чтобы ответить на этот вопрос. Это добавление, вычитание, умножение, деление, возведение в степень (использование символа ^) и несколько основных функций, таких как sqrt. Он поддерживает группировку с использованием ( ... ) и получает правильные правила приоритета и ассоциативности .

public static double eval(final String str) {
    return new Object() {
        int pos = -1, ch;

        void nextChar() {
            ch = (++pos < str.length()) ? str.charAt(pos) : -1;
        }

        boolean eat(int charToEat) {
            while (ch == ' ') nextChar();
            if (ch == charToEat) {
                nextChar();
                return true;
            }
            return false;
        }

        double parse() {
            nextChar();
            double x = parseExpression();
            if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
            return x;
        }

        // Grammar:
        // expression = term | expression `+` term | expression `-` term
        // term = factor | term `*` factor | term `/` factor
        // factor = `+` factor | `-` factor | `(` expression `)`
        //        | number | functionName factor | factor `^` factor

        double parseExpression() {
            double x = parseTerm();
            for (;;) {
                if      (eat('+')) x += parseTerm(); // addition
                else if (eat('-')) x -= parseTerm(); // subtraction
                else return x;
            }
        }

        double parseTerm() {
            double x = parseFactor();
            for (;;) {
                if      (eat('*')) x *= parseFactor(); // multiplication
                else if (eat('/')) x /= parseFactor(); // division
                else return x;
            }
        }

        double parseFactor() {
            if (eat('+')) return parseFactor(); // unary plus
            if (eat('-')) return -parseFactor(); // unary minus

            double x;
            int startPos = this.pos;
            if (eat('(')) { // parentheses
                x = parseExpression();
                eat(')');
            } else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
                while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
                x = Double.parseDouble(str.substring(startPos, this.pos));
            } else if (ch >= 'a' && ch <= 'z') { // functions
                while (ch >= 'a' && ch <= 'z') nextChar();
                String func = str.substring(startPos, this.pos);
                x = parseFactor();
                if (func.equals("sqrt")) x = Math.sqrt(x);
                else if (func.equals("sin")) x = Math.sin(Math.toRadians(x));
                else if (func.equals("cos")) x = Math.cos(Math.toRadians(x));
                else if (func.equals("tan")) x = Math.tan(Math.toRadians(x));
                else throw new RuntimeException("Unknown function: " + func);
            } else {
                throw new RuntimeException("Unexpected: " + (char)ch);
            }

            if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation

            return x;
        }
    }.parse();
}

Пример :

System.out.println(eval("((4 - 2^3 + 1) * -sqrt(3*3+4*4)) / 2"));

Выход: 7.5 (что правильно)


Парсер является рекурсивным парсером спуска , поэтому внутренне использует отдельные методы анализа для каждого уровня приоритета оператора в своей грамматике. Я сохранил его, поэтому его легко модифицировать, но вот несколько идей, которые вы можете расширить, с помощью:

  • Переменные: бит анализатора, который читает имена функций, может быть легко изменен для обработки собственных переменных, путем поиска имен в таблице переменных, переданных в метод eval, например Map<String,Double> variables.
  • Отдельная компиляция и оценка: что, если, добавив поддержку переменных, вы хотели бы оценить одно и то же выражение миллионы раз с измененными переменными, без разбора его каждый раз? Возможно. Сначала определите интерфейс, который будет использоваться для оценки прекомпилированного выражения:
    @FunctionalInterface
    interface Expression {
        double eval();
    }
    
    Теперь измените все методы, возвращающие double s, поэтому вместо этого они возвращают экземпляр этого интерфейса. Синтаксис лямбды Java 8 отлично подходит для этого. Пример одного из измененных методов:
    Expression parseExpression() {
        Expression x = parseTerm();
        for (;;) {
            if (eat('+')) { // addition
                Expression a = x, b = parseTerm();
                x = (() -> a.eval() + b.eval());
            } else if (eat('-')) { // subtraction
                Expression a = x, b = parseTerm();
                x = (() -> a.eval() - b.eval());
            } else {
                return x;
            }
        }
    }
    
    Создает рекурсивное дерево объектов Expression, представляющих скомпилированное выражение (дерево синтаксиса ). Затем вы можете скомпилировать его один раз и повторно оценить его разными значениями:
    public static void main(String[] args) {
        Map<String,Double> variables = new HashMap<>();
        Expression exp = parse("x^2 - x + 2", variables);
        for (double x = -20; x <= +20; x++) {
            variables.put("x", x);
            System.out.println(x + " => " + exp.eval());
        }
    }
    
  • Различные типы данных: вместо double вы можете изменить оценщика, чтобы использовать что-то более мощное, например BigDecimal, или класс, который реализует комплексные числа или рациональные числа (дроби). Вы даже можете использовать Object, позволяя смешивать типы данных в выражениях, как и в реальном языке программирования. :)

Весь код в этом ответе опубликовал в общедоступном домене . Получайте удовольствие!

171
ответ дан Boann 26 August 2018 в 15:46
поделиться

Кажется, что JEP должен выполнить задание

5
ответ дан Bozho 26 August 2018 в 15:46
поделиться

В этой статье указаны три разных подхода, один из которых - JEXL из Apache и позволяет сценарии, содержащие ссылки на java-объекты.

7
ответ дан Brad Parks 26 August 2018 в 15:46
поделиться

Попробуйте использовать следующий пример кода, используя Javascript-механизм JDK1.6 с обработкой ввода кода.

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class EvalUtil {
private static ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
public static void main(String[] args) {
    try {
        System.out.println((new EvalUtil()).eval("(((5+5)/2) > 5) || 5 >3 "));
        System.out.println((new EvalUtil()).eval("(((5+5)/2) > 5) || true"));
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public Object eval(String input) throws Exception{
    try {
        if(input.matches(".*[a-zA-Z;~`#$_{}\\[\\]:\\\\;\"',\\.\\?]+.*")) {
            throw new Exception("Invalid expression : " + input );
        }
        return engine.eval(input);
    } catch (Exception e) {
        e.printStackTrace();
        throw e;
    }
 }
}
2
ответ дан Bruce 26 August 2018 в 15:46
поделиться

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

String math = "1+4";

if (math.split("+").length == 2) {
    //do calculation
} else if (math.split("-").length == 2) {
    //do calculation
} ...

. Это становится намного сложнее, если вы хотите иметь дело с несколькими операциями типа «4 + 5 * 6 ".

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

5
ответ дан BruteForce 26 August 2018 в 15:46
поделиться

Это фактически дополняет ответ, данный @Boann. У этого есть небольшая ошибка, которая вызывает «-2 ^ 2», чтобы дать ошибочный результат -4.0. Проблема для этого - точка, в которой в его оценке оценивается степень возведения в степень. Просто переместите экспоненцию в блок parseTerm (), и все будет хорошо. Посмотрите ниже, что @ Ответ Боанна слегка изменен. Модификация содержится в комментариях.

public static double eval(final String str) {
    return new Object() {
        int pos = -1, ch;

        void nextChar() {
            ch = (++pos < str.length()) ? str.charAt(pos) : -1;
        }

        boolean eat(int charToEat) {
            while (ch == ' ') nextChar();
            if (ch == charToEat) {
                nextChar();
                return true;
            }
            return false;
        }

        double parse() {
            nextChar();
            double x = parseExpression();
            if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
            return x;
        }

        // Grammar:
        // expression = term | expression `+` term | expression `-` term
        // term = factor | term `*` factor | term `/` factor
        // factor = `+` factor | `-` factor | `(` expression `)`
        //        | number | functionName factor | factor `^` factor

        double parseExpression() {
            double x = parseTerm();
            for (;;) {
                if      (eat('+')) x += parseTerm(); // addition
                else if (eat('-')) x -= parseTerm(); // subtraction
                else return x;
            }
        }

        double parseTerm() {
            double x = parseFactor();
            for (;;) {
                if      (eat('*')) x *= parseFactor(); // multiplication
                else if (eat('/')) x /= parseFactor(); // division
                else if (eat('^')) x = Math.pow(x, parseFactor()); //exponentiation -> Moved in to here. So the problem is fixed
                else return x;
            }
        }

        double parseFactor() {
            if (eat('+')) return parseFactor(); // unary plus
            if (eat('-')) return -parseFactor(); // unary minus

            double x;
            int startPos = this.pos;
            if (eat('(')) { // parentheses
                x = parseExpression();
                eat(')');
            } else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
                while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
                x = Double.parseDouble(str.substring(startPos, this.pos));
            } else if (ch >= 'a' && ch <= 'z') { // functions
                while (ch >= 'a' && ch <= 'z') nextChar();
                String func = str.substring(startPos, this.pos);
                x = parseFactor();
                if (func.equals("sqrt")) x = Math.sqrt(x);
                else if (func.equals("sin")) x = Math.sin(Math.toRadians(x));
                else if (func.equals("cos")) x = Math.cos(Math.toRadians(x));
                else if (func.equals("tan")) x = Math.tan(Math.toRadians(x));
                else throw new RuntimeException("Unknown function: " + func);
            } else {
                throw new RuntimeException("Unexpected: " + (char)ch);
            }

            //if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation -> This is causing a bit of problem

            return x;
        }
    }.parse();
}
2
ответ дан Community 26 August 2018 в 15:46
поделиться

Вы можете легко оценивать выражения, если ваше приложение Java уже обращается к базе данных без использования каких-либо других JAR.

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

Например, в Sql Server или Sqlite

select (((12.10 +12.0))/ 233.0) amount

и в Oracle

select (((12.10 +12.0))/ 233.0) amount from dual;

Преимущество использования БД состоит в том, что вы можете одновременно оценить множество выражений. Кроме того, большинство БД позволит вам использовать очень сложные выражения и также будет иметь ряд дополнительных функций, которые можно назвать необходимыми.

Однако производительность может пострадать, если много отдельных выражений нужно оценивать индивидуально, особенно когда БД находится на сетевом сервере.

Ниже рассматриваются проблемы производительности в некоторой степени, используя базу данных Sqlite in-memory.

Вот полный рабочий пример в Java

Class. forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:");
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery( "select (1+10)/20.0 amount");
rs.next();
System.out.println(rs.getBigDecimal(1));
stat.close();
conn.close();

Конечно, вы могли бы расширить вышеупомянутый код, чтобы обрабатывать несколько вычислений одновременно.

ResultSet rs = stat.executeQuery( "select (1+10)/20.0 amount, (1+100)/20.0 amount2");
12
ответ дан DAB 26 August 2018 в 15:46
поделиться
import java.util.*;
StringTokenizer st;
int ans;

public class check { 
   String str="7 + 5";
   StringTokenizer st=new StringTokenizer(str);

   int v1=Integer.parseInt(st.nextToken());
   String op=st.nextToken();
   int v2=Integer.parseInt(st.nextToken());

   if(op.equals("+")) { ans= v1 + v2; }
   if(op.equals("-")) { ans= v1 - v2; }
   //.........
}
1
ответ дан developer033 26 August 2018 в 15:46
поделиться

Можно преобразовать любую строку выражения в нотации infix в постфиксную нотацию, используя алгоритм shing-yard Джикстры . Результат алгоритма затем может служить входом в постфиксный алгоритм с возвратом результата выражения.

Здесь я написал статью об этом , с реализацией в java

1
ответ дан Emmanuel John 26 August 2018 в 15:46
поделиться

Еще один способ - использовать Spring Expression Language или SpEL, который делает намного больше, а также оценивает математические выражения, поэтому может немного переборщить. Вам не нужно использовать Spring framework для использования этой библиотеки выражений, поскольку она является автономной. Копирование примеров из документации SpEL:

ExpressionParser parser = new SpelExpressionParser();
int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2 
double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double.class); //24.0

Ниже приведены более сжатые примеры Spel здесь и полные документы здесь

6
ответ дан Faheem Sohail 26 August 2018 в 15:46
поделиться

Правильный способ решить это с помощью lexer и синтаксического анализатора . Вы можете написать простые версии из них самостоятельно, или эти страницы также имеют ссылки на Java-лексеры и парсеры.

Создание рекурсивного синтаксического анализа является хорошим упражнением.

25
ответ дан Greg Hewgill 26 August 2018 в 15:46
поделиться

Для моего университетского проекта я искал анализатор / оценщик, поддерживающий как основные формулы, так и более сложные уравнения (особенно повторяющиеся операторы). Я нашел очень хорошую библиотеку с открытым исходным кодом для JAVA и .NET под названием mXparser.

http://mathparser.org/ / g4]

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

http://mathparser.org/api/

И несколько примеров

1 - Простая механика

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

2 - Пользовательские аргументы и константы

Argument x = new Argument("x = 10");
Constant a = new Constant("a = pi^2");
Expression e = new Expression("cos(a*x)", x, a);
double v = e.calculate()

3 - Пользователь определенные функции

Function f = new Function("f(x, y, z) = sin(x) + cos(y*z)");
Expression e = new Expression("f(3,2,5)", f);
double v = e.calculate()

4 - Итерация

Expression e = new Expression("sum( i, 1, 100, sin(i) )");
double v = e.calculate()

С наилучшими пожеланиями

9
ответ дан HoldOffHunger 26 August 2018 в 15:46
поделиться

Как насчет чего-то вроде этого:

String st = "10+3";
int result;
for(int i=0;i<st.length();i++)
{
  if(st.charAt(i)=='+')
  {
    result=Integer.parseInt(st.substring(0, i))+Integer.parseInt(st.substring(i+1, st.length()));
    System.out.print(result);
  }         
}

и выполните аналогичные действия для каждого другого математического оператора соответственно.

1
ответ дан keyser 26 August 2018 в 15:46
поделиться

Вы можете взглянуть на структуру Symja :

ExprEvaluator util = new ExprEvaluator(); 
IExpr result = util.evaluate("10-40");
System.out.println(result.toString()); // -> "-30" 

Обратите внимание, что можно определить более сложные выражения:

// D(...) gives the derivative of the function Sin(x)*Cos(x)
IAST function = D(Times(Sin(x), Cos(x)), x);
IExpr result = util.evaluate(function);
// print: Cos(x)^2-Sin(x)^2
3
ответ дан Laurent Magnin 26 August 2018 в 15:46
поделиться

Для запуска javascript можно использовать внешнюю библиотеку, такую ​​как RHINO или NASHORN. И javascript может оценивать простую формулу без парсинга строки. Не влияет на производительность, если код написан хорошо. Ниже приведен пример с RHINO -

public class RhinoApp {
    private String simpleAdd = "(12+13+2-2)*2+(12+13+2-2)*2";

public void runJavaScript() {
    Context jsCx = Context.enter();
    Context.getCurrentContext().setOptimizationLevel(-1);
    ScriptableObject scope = jsCx.initStandardObjects();
    Object result = jsCx.evaluateString(scope, simpleAdd , "formula", 0, null);
    Context.exit();
    System.out.println(result);
}
1
ответ дан Manish 26 August 2018 в 15:46
поделиться

Вы также можете попробовать интерпретатор BeanShell :

Interpreter interpreter = new Interpreter();
interpreter.eval("result = (7+21*6)/(32-27)");
System.out.println(interpreter.get("result"));
12
ответ дан marciowerner 26 August 2018 в 15:46
поделиться

Класс Java, который может оценивать математические выражения:

package test;

public class Calculator {

    public static Double calculate(String expression){
        if (expression == null || expression.length() == 0) {
            return null;
        }
        return calc(expression.replace(" ", ""));
    }
    public static Double calc(String expression) {

        if (expression.startsWith("(") && expression.endsWith(")")) {
            return calc(expression.substring(1, expression.length() - 1));
        }
        String[] containerArr = new String[]{expression};
        double leftVal = getNextOperand(containerArr);
        expression = containerArr[0];
        if (expression.length() == 0) {
            return leftVal;
        }
        char operator = expression.charAt(0);
        expression = expression.substring(1);

        while (operator == '*' || operator == '/') {
            containerArr[0] = expression;
            double rightVal = getNextOperand(containerArr);
            expression = containerArr[0];
            if (operator == '*') {
                leftVal = leftVal * rightVal;
            } else {
                leftVal = leftVal / rightVal;
            }
            if (expression.length() > 0) {
                operator = expression.charAt(0);
                expression = expression.substring(1);
            } else {
                return leftVal;
            }
        }
        if (operator == '+') {
            return leftVal + calc(expression);
        } else {
            return leftVal - calc(expression);
        }

    }

    private static double getNextOperand(String[] exp){
        double res;
        if (exp[0].startsWith("(")) {
            int open = 1;
            int i = 1;
            while (open != 0) {
                if (exp[0].charAt(i) == '(') {
                    open++;
                } else if (exp[0].charAt(i) == ')') {
                    open--;
                }
                i++;
            }
            res = calc(exp[0].substring(1, i - 1));
            exp[0] = exp[0].substring(i);
        } else {
            int i = 1;
            if (exp[0].charAt(0) == '-') {
                i++;
            }
            while (exp[0].length() > i && isNumber((int) exp[0].charAt(i))) {
                i++;
            }
            res = Double.parseDouble(exp[0].substring(0, i));
            exp[0] = exp[0].substring(i);
        }
        return res;
    }


    private static boolean isNumber(int c) {
        int zero = (int) '0';
        int nine = (int) '9';
        return (c >= zero && c <= nine) || c =='.';
    }

    public static void main(String[] args) {
        System.out.println(calculate("(((( -6 )))) * 9 * -1"));
        System.out.println(calc("(-5.2+-5*-5*((5/4+2)))"));

    }

}
0
ответ дан MultiplyByZer0 26 August 2018 в 15:46
поделиться

, если мы собираемся его реализовать, мы можем использовать приведенный ниже алгоритм: -

  1. Пока еще есть токены для чтения, 1.1. Получите следующий токен. 1.2 Если токен: 1.2.1 Число: нажмите на стек значений. 1.2.2. Переменная: получить ее значение и нажать на стек значений. 1.2.3 Левая скобка: надавите на стек оператора. 1.2.4 Правильная скобка:
     1 While the thing on top of the operator stack is not a 
       left parenthesis,
         1 Pop the operator from the operator stack.
         2 Pop the value stack twice, getting two operands.
         3 Apply the operator to the operands, in the correct order.
         4 Push the result onto the value stack.
     2 Pop the left parenthesis from the operator stack, and discard it.
    
    1.2.5 Оператор (назовите его thisOp):
     1 While the operator stack is not empty, and the top thing on the
       operator stack has the same or greater precedence as thisOp,
       1 Pop the operator from the operator stack.
       2 Pop the value stack twice, getting two operands.
       3 Apply the operator to the operands, in the correct order.
       4 Push the result onto the value stack.
     2 Push thisOp onto the operator stack.
    
  2. Пока стек оператора не пуст, 1 Выполните посылку оператора из стека оператора. 2 Выполните дважды стек значений, получив два операнда. 3 Примените оператор к операндам в правильном порядке. 4 Нажмите результат в стек значений.
  3. В этот момент стек оператора должен быть пустым, а стек значений должен иметь только одно значение, которое является конечным результатом.
5
ответ дан Prashant Gautam 26 August 2018 в 15:46
поделиться

Слишком поздно, чтобы ответить, но я столкнулся с такой же ситуацией, чтобы оценить выражение в java, это может помочь кому-то

MVEL выполнять вычисления времени выполнения, мы можем написать java-код в String чтобы получить его в этом.

    String expressionStr = "x+y";
    Map<String, Object> vars = new HashMap<String, Object>();
    vars.put("x", 10);
    vars.put("y", 20);
    ExecutableStatement statement = (ExecutableStatement) MVEL.compileExpression(expressionStr);
    Object result = MVEL.executeExpression(statement, vars);
1
ответ дан Saravana 26 August 2018 в 15:46
поделиться

Это еще одна интересная альтернатива https://github.com/Shy-Ta/expression-evaluator-demo

. Использование очень простое и выполняет задание, например:

  ExpressionsEvaluator evalExpr = ExpressionsFactory.create("2+3*4-6/2");  
  assertEquals(BigDecimal.valueOf(11), evalExpr.eval()); 
6
ответ дан Scorpion 26 August 2018 в 15:46
поделиться

Еще один вариант: https://github.com/stefanhaustein/expressionparser

Я применил это, чтобы иметь простой, но гибкий вариант, позволяющий обоим:

Связанный выше TreeBuilder является частью демонстрационного пакета CAS , который выполняет символический вывод. Существует также пример BASIC-интерпретатора , и я начал использовать интерпретатор TypeScript , используя его.

1
ответ дан Stefan Haustein 26 August 2018 в 15:46
поделиться
2
ответ дан Taher Khorshidi 26 August 2018 в 15:46
поделиться

ЗДЕСЬ - это другая библиотека с открытым исходным кодом на GitHub с именем EvalEx.

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

15
ответ дан Tanvir 26 August 2018 в 15:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: