2012-02-17 3 views
1

Я нашел функцию где-то в сети, которая может выполнять строковые уравнения. Например, у меня может быть строка типа «1 + 5». Когда я передаю его функции, он возвращает ответ. В моем приложении я вытягиваю формулы из базы данных и заменяю неизвестные номера (например, x, y или z) фактическими числами (1,2,3,4,5 и т. Д.), Введенными пользователем при использовании приложения. Однако некоторые из формул, которые мне нужно выполнить, требуют квадратных корней. Когда я пытаюсь передать строку, содержащую функцию Math.Sqrt(), она дает мне ошибку, говорящую о том, что она является функцией без исправления. Есть ли способ изменить функцию для распознавания этой функции?Как распознать функции таблицы данных

Функция использует таблицу данных. Вот код:

public static double executeFormula(string expression) 
{ 
    System.Data.DataTable table = new System.Data.DataTable(); 
    table.Columns.Add("expression", string.Empty.GetType(), expression); 
    System.Data.DataRow row = table.NewRow(); 
    table.Rows.Add(row); 
    return double.Parse((string)row["expression"]); 
} 

Спасибо, ребята!

+0

Что именно вы используете 'из Интернета где-то'? – Randy

+0

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

+0

Вместо 'string.Empty.GetType() 'вы можете написать' typeof (string) '. –

ответ

3

Используйте nCalc и сделайте с ним.

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

+0

+1 - спасибо за указатель на nCalc. Выглядит полезно! – dash

+0

@ dash: Это так. Мы используем его для решения двух основных проблем. Первый, чтобы выполнить некоторые сложные математические функции, которые неизвестны до времени выполнения. Во-вторых, мы использовали его для реализации простого механизма правил обработки страниц. Очень прост в использовании и довольно чертовски быстро загружается. – NotMe

+0

Awesome. Лучшая библиотека! Спасибо! – Cityonhill93

0

Вы можете создавать «текстовые функции», которые люди смогут распознавать и использовать, и что вы можете анализировать свою программу. Взгляните на WolframAlpha или MS Math 4.0. Например, вы можете сделать примерно следующее:

if(str.IndexOf("sqrt")>-1) 
{ 
    //replace sqrt for the actual Math.Sqrt() function 
} 

Удачи вам!

2

Я боюсь, что ответ отрицательный, как вы его написали. Функция, которую вы показываете, использует функцию DataColumn в таблицах данных, свойство Expression.

эффективно, она поддерживает многие из операторов вы бы найти в SQL:

Из документации:

OPERATORS 

Concatenation is allowed using Boolean AND, OR, and NOT operators. You can use parentheses to group clauses and force precedence. The AND operator has precedence over other operators. For example: 

(LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John' 

When creating comparison expressions, the following operators are allowed: 

< 

> 

<= 

>= 

<> 

= 

IN 

LIKE 

The following arithmetic operators are also supported in expressions: 

+ (addition) 

- (subtraction) 

* (multiplication) 

/(division) 

% (modulus) 

STRING OPERATORS 

To concatenate a string, use the + character. Whether string comparisons are case-sensitive or not is determined by the value of the DataSet class's CaseSensitive property. However, you can override that value with the DataTable class's CaseSensitive property. 

WILDCARD CHARACTERS 

Both the * and % can be used interchangeably for wildcards in a LIKE comparison. If the string in a LIKE clause contains a * or %, those characters should be escaped in brackets ([]). If a bracket is in the clause, the bracket characters should be escaped in brackets (for example [[] or []]). A wildcard is allowed at the beginning and end of a pattern, or at the end of a pattern, or at the beginning of a pattern. For example: 

"ItemName LIKE '*product*'" 

"ItemName LIKE '*product'" 

"ItemName LIKE 'product*'" 

Wildcards are not allowed in the middle of a string. For example, 'te*xt' is not allowed. 

PARENT/CHILD RELATION REFERENCING 

A parent table may be referenced in an expression by prepending the column name with Parent. For example, the Parent.Price references the parent table's column named Price. 

A column in a child table may be referenced in an expression by prepending the column name with Child. However, because child relationships may return multiple rows, you must include the reference to the child column in an aggregate function. For example, Sum(Child.Price) would return the sum of the column named Price in the child table. 

If a table has more than one child, the syntax is: Child(RelationName). For example, if a table has two child tables named Customers and Orders, and the DataRelation object is named Customers2Orders, the reference would be: 

Avg(Child(Customers2Orders).Quantity) 

AGGREGATES 

The following aggregate types are supported: 

Sum (Sum) 

Avg (Average) 

Min (Minimum) 

Max (Maximum) 

Count (Count) 

StDev (Statistical standard deviation) 

Var (Statistical variance). 

Aggregates are usually performed along relationships. Create an aggregate expression by using one of the functions listed above and a child table column as detailed in PARENT/CHILD RELATION REFERENCING above. For example: 

Avg(Child.Price) 

Avg(Child(Orders2Details).Price) 

К сожалению, квадратный корень не одна из функций, которые вы можете использовать. Однако, поскольку вы используете DataTable, вы можете просто перебирать строки и вычислять SquareRoot непосредственно из значения столбца. Представьте, что у вас есть столбец под названием «MyNumber». Вы могли бы сделать что-то вроде:

myDataTable.Columns.Add(new DataColumn() { Name = "MySquareRoot", DataType = typeof(Double)}); 

foreach(DataRow row in myDataTable.Rows) 
{ 
    myDataTable["MySquareRoot"] = Math.Sqrt(Convert.ToDouble(myDataTable["MyNumber"])); 
} 

Вы могли бы поставить такую ​​функцию в Extension метод, если вы хотите.

В качестве альтернативы вы можете обращаться с вашими формулами где-то в другом месте; вместо использования DataTable для моделирования ваших данных, вы можете использовать класс. Сам класс может иметь свойства (или список или коллекцию), которые представляют ваши данные, и методы, действующие на ваши данные, - тогда вы можете использовать любую функцию, которую вы хотите на C#.

0

Посмотрите проект CodePlex flee. Flee позволяет вам оценивать строковые выражения, такие как "sqrt(a^2 + b^2)" во время выполнения.

Смежные вопросы