Вычисление простого оператора с 4 арифметическими операторами не работает - PullRequest
0 голосов
/ 08 июля 2019

Я пытаюсь выучить c #, и в настоящее время я пытаюсь создать калькулятор, в котором вы можете ввести столько символов, сколько захотите, и он покажет вам окончательный результат ...

Для моегопример я буду использовать List<string> Statement = {"12", "/", "4", "*", "3"}

string numbers = "0123456789";

for (int i = 0; i < Statement.Count; i++)
            {
                if (!numbers.Contains(Statement[i][0]))
                {
                    Statement[i] = Convert.ToString(Operations.Compute(Convert.ToInt32(Statement[i - 1]), Convert.ToInt32(Statement[i + 1]), Statement[i]));
                    Statement.RemoveAt(i - 1);
                    Statement.RemoveAt(i + 1);
                    i--;
                }
            }

Операции вычисляются:

class Operations
    {
        public static float Compute(float num1, float num2, string OpType)
        {
            if(OpType == "+") { return num1 + num2; }
            if(OpType == "-") { return num1 - num2; }
            if(OpType == "*") { return num1 * num2; }
            if(OpType == "/") { return num1 / num2; }

            return 0;
        }
    }

Когда я запускаю программу и перечисляю все элементы из Statement с простым циклом foreach, я ожидаючтобы вернуть 9 (так как 12/4 * 3 = 9).

Вместо этого перечисляются следующие три числа: 3, 4, 3

Кажется, что всегда вычисляются первые два числа изатем перечислите остальные.

Ответы [ 2 ]

0 голосов
/ 08 июля 2019

Для вычисления формулы я предлагаю использовать стековую машину.В общем случае необходимо преобразовать исходную формулу в RPN (обратная польская запись) с помощью Алгоритм шунтирования .Однако, если у вас есть только 4 инфиксные двоичные арифметические операции, вы можете поместить вычисление как

  // Let's extract the model: all possible infix binary operations
  Dictionary<string, Func<double, double, double>> operations = 
    new Dictionary<string, Func<double, double, double>>() {
      { "+", (x, y) => x + y },
      { "-", (x, y) => x - y },
      { "*", (x, y) => x * y },
      { "/", (x, y) => x / y },
  };

  List<string> data = new List<string>() {
    "12", "/", "4", "*", "3"
  };

  // Stack for data
  Stack<double> items = new Stack<double>();
  // Stack for operations
  Stack<Func<double, double, double>> ops = new Stack<Func<double, double, double>>();

  foreach (string item in data)
    if (double.TryParse(item, out double v)) // do we have number? 
      if (ops.Any()) // do we have an operation? 
        // if yes, execute it; put the outcome on the stack 
        items.Push(ops.Pop()(items.Pop(), v)); 
      else
        // if no operation, just put item on the stack
        items.Push(v);
    else // operation should be put on its stack
      ops.Push(operations[item]);

  double result = items.Pop();
0 голосов
/ 08 июля 2019

Я только что переключился с Statement.RemoveAt(i + 1); на Statement.RemoveAt(i);, и это работает.

Это потому, что когда вы делаете Statement.RemoveAt(i - 1);, положение i изменяется, и поэтому Statement.RemoveAt(i + 1); удаляет элемент после того элемента, который вы на самом делехочу удалить.Спасибо за вашу помощь!

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