решение математического выражения - PullRequest
3 голосов
/ 05 октября 2011

Я хочу оценить математическое выражение, которое пользователь вводит в текстовое поле. Я сделал это до сих пор

string equation, finalString;
equation = textBox1.Text;
StringBuilder stringEvaluate = new StringBuilder(equation);
stringEvaluate.Replace("sin", "math.sin");
stringEvaluate.Replace("cos", "math.cos");
stringEvaluate.Replace("tan", "math.tan");
stringEvaluate.Replace("log", "math.log10");
stringEvaluate.Replace("e^", "math.exp");
finalString = stringEvaluate.ToString();
StringBuilder replaceI = new StringBuilder(finalString);
replaceI.Replace("x", "i");

double a;
for (int i = 0; i<5 ; i++)
 {
  a = double.Parse(finalStringI);
  if(a<0)
    break;
 }

при запуске этой программы выдает ошибку "Input string was not in a correct format." и выделяет a=double.Parse(finalStringI);

Я использовал предопределенное выражение a = i * math.log10 (i) -1.2, и оно работает, но когда я ввожу то же самое в текстовое поле, это не так. Я провел некоторый поиск, и он нашел какое-то отношение к компиляции кода во время выполнения.

есть идеи как это сделать? Я абсолютный новичок. спасибо:)

Ответы [ 4 ]

2 голосов
/ 05 октября 2011

Проблема в вашем stringEvaluate StringBuilder. Когда вы заменяете «sin» на «math.sin», содержимое в stringEvaluate остается строкой. Вы правильно поняли, но ошибка, которую вы получаете, из-за этого факта.

Math.sin - это метод внутри класса Math, поэтому он не может быть использован, как при вызове a = double.Parse(finalStringI);.

Было бы довольно сложно выполнить вашу задачу, но я бы пошел по этому пути:

  1. Создайте класс (возможно, назовите его Expression).
  2. Члены класса Expression могут включать списки операторов и операндов и, возможно, двойное число, называемое solution.
  3. Передайте этому классу строку при создании экземпляра и разбейте ее на части, используя класс StringBuilder. Например, если вы столкнулись с «грехом», добавьте Math.sin в коллекцию операторов (из которых я бы использовал тип object).
  4. Каждый оператор и операнд в указанной строке должны быть помещены в две коллекции.
  5. Создайте метод, который оценивает элементы внутри оператора и коллекцию операндов соответственно. Это может привести к сложным вычислениям с более чем 2 операторами, так как вам придется реализовать алгоритм PEMDAS-esque, чтобы переупорядочить коллекции, чтобы они соответствовали порядку операций (и, таким образом, достигали правильных решений).

Надеюсь, это поможет:)

0 голосов
/ 05 октября 2011

Посмотрите на эту запись в блоге:

http://www.c -sharpcorner.com / UploadFile / mgold / CodeDomCalculator08082005003253AM / CodeDomCalculator.aspx

Звучит так, будто это в значительной степени соответствует тому, что вы пытаетесь сделать. Оценка математических выражений не так проста, как простой анализ double (который действительно будет работать только для строк типа «1.234», а не «1 + 2.34»), но, очевидно, это возможно.

0 голосов
/ 05 октября 2011

Вы можете использовать функцию eval, включенную в структуру для кода JScript.NET.

Подробнее: http://odetocode.com/code/80.aspx

Или, если вы не боитесь использовать классыпомеченный как «устарел», это действительно просто:

static string EvalExpression(string s)
{
    return Microsoft.JScript.Eval.JScriptEvaluate(s, null, Microsoft.JScript.Vsa.VsaEngine.CreateEngine()).ToString();
}

Например, введите "Math.cos(Math.PI / 3)" и получите результат "0.5" (который является правильным косинусом 60 градусов)

0 голосов
/ 05 октября 2011

Методы .Parse (Int.Parse, double.Parse и т. Д.) only принимают строку, например "25" или "3.141", и преобразуют ее всоответствующий тип значения (int 25 или double 3.141).Они не будут оценивать математические выражения!

Вам, скорее всего, придется написать свой собственный анализатор текста и дерево разбора, или исследовать генерацию кода во время выполнения или эмиссию кода MSIL.

Ни одна из тем действительно не может быть охвачена в формате вопросов и ответов ответов StackOverflow.

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