Parse Math Expression - PullRequest
       0

Parse Math Expression

8 голосов
/ 20 октября 2010

Есть ли простой способ проанализировать простое математическое выражение, представленное в виде строки, такой как (x + (2 * x) / (1-x)), предоставить значение для x и получить результат?

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

Если она имеет какие-либо отличия, я использую .NET 4.0.

Ответы [ 9 ]

10 голосов
/ 20 октября 2010

Я настаиваю на том, чтобы не выбирать существующий оценщик обобщенных выражений вместо специализированного математического оценщика. Причина этого в том, что оценщики выражений не ограничиваются только математикой. Умный человек может использовать это для создания экземпляра любого типа в платформе и вызова любого метода для этого типа, что позволит ему делать некоторые явно нежелательные вещи. Например: new System.Net.WebClient().DownloadFile("illegalchildpornurl", "C:\openme.gif") будет хорошо оценивать большинство из них и будет делать то, что звучит, как будто (и в то же время сделает вас преступником).

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

8 голосов
/ 05 марта 2016

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

Пример 1 - простая формула

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

Пример 2 - формула с переменными, функциями и т. Д.

Argument x = new Argument("x = 2");
Constant a = new Constant("a = sin(10)");
Function f = new Function("f(t) = t^2");
Expression e = new Expression("2*x + a - f(10)", x, a, f);
double v = e.calculate();

https://mxparser.codeplex.com/

http://mathparser.org/

Найден недавно - вы можете попробовать синтаксис (и просмотреть пример использования) через приложение Scalar Calculator , которое работает на mXparser.

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

С уважением

5 голосов
/ 20 октября 2010

Вы можете попробовать использовать DataTable.Compute .

Связанный является DataColumn.Expression .

Также проверьте: Делать математику в vb.net, как Eval в JavaScript

Примечание: я сам этим не пользовался.

3 голосов
/ 27 января 2014

Я бы также взглянул на Jace (https://github.com/pieterderycke/Jace). Jace - это высокопроизводительный математический анализатор и механизм вычислений, который поддерживает все разновидности .NET (.NET 4.x, Windows Phone, Windows Store, ...). Jace также доступен через NuGet: https://www.nuget.org/packages/Jace

2 голосов
/ 15 октября 2017

Вот один из способов сделать это. Этот код написан на Java. Обратите внимание, что сейчас он не обрабатывает отрицательные числа, но вы можете добавить это.

public class ExpressionParser {
public double eval(String exp, Map<String, Double> vars){
    int bracketCounter = 0;
    int operatorIndex = -1;

    for(int i=0; i<exp.length(); i++){
        char c = exp.charAt(i);
        if(c == '(') bracketCounter++;
        else if(c == ')') bracketCounter--;
        else if((c == '+' || c == '-') && bracketCounter == 0){
            operatorIndex = i;
            break;
        }
        else if((c == '*' || c == '/') && bracketCounter == 0 && operatorIndex < 0){
            operatorIndex = i;
        }
    }
    if(operatorIndex < 0){
        exp = exp.trim();
        if(exp.charAt(0) == '(' && exp.charAt(exp.length()-1) == ')')
            return eval(exp.substring(1, exp.length()-1), vars);
        else if(vars.containsKey(exp))
            return vars.get(exp);
        else
            return Double.parseDouble(exp);
    }
    else{
        switch(exp.charAt(operatorIndex)){
            case '+':
                return eval(exp.substring(0, operatorIndex), vars) + eval(exp.substring(operatorIndex+1), vars);
            case '-':
                return eval(exp.substring(0, operatorIndex), vars) - eval(exp.substring(operatorIndex+1), vars);
            case '*':
                return eval(exp.substring(0, operatorIndex), vars) * eval(exp.substring(operatorIndex+1), vars);
            case '/':
                return eval(exp.substring(0, operatorIndex), vars) / eval(exp.substring(operatorIndex+1), vars);
        }
    }
    return 0;
}

}

Вам необходимо импортировать java.util.Map.

Вот как я использую этот код:

    ExpressionParser p = new ExpressionParser();
    Map vars = new HashMap<String, Double>();
    vars.put("x", 2.50);
    System.out.println(p.eval(" 5 + 6 * x - 1", vars));
1 голос
/ 20 октября 2010
1 голос
/ 20 октября 2010

Другой вариант, на который вы можете обратить внимание, - это функциональность Spring.NET Framework для оценки выражений . Это может сделать гораздо больше, чем математика тоже.

Однако весь Spring.NET Framework может оказаться излишним для ваших нужд, если вам не требуются остальные функции.

0 голосов
/ 06 февраля 2015

Я рекомендую вам использовать MEEL для этого.

// parse string to IExpression (symbolic type)
IExpression expression = BaseExpression.Parse("(x+(2*x)/(1-x))");

// create your own collection for attributes
var attributes = new MathAttributeCollection();
// create local variable named "x" with value 5
var attributeX = new ScalarAttrInt("x") {Value = new ScalarConstInt(5)};
attributes.Add(attributeX);

// execute math expression where x=5
var result = expression.Execute(attributes);

MessageBox.Show(result.GetText());
// result: 2.5
0 голосов
/ 30 апреля 2013

Как я уже отвечал в этой теме ( Best Free C # Math Parser с использованием переменных, пользовательских функций, пользовательских операторов ), вы можете использовать Mathos Parser , который вы можете просто вставить вваш исходный код.

        Mathos.Parser.MathParser parser = new Mathos.Parser.MathParser();

        string expr = "(x+(2*x)/(1-x))"; // the expression

        decimal result = 0; // the storage of the result

        parser.LocalVariables.Add("x", 41); // 41 is the value of x

        result = parser.Parse(expr); // parsing

        Console.WriteLine(result); // 38.95
...