Консольний калькулятор виразів

Створити програму – калькулятор математичних виразів, що вводяться користувачем, з клавіатури. Операнди – дійсні числа. Операції – додавання, множення, віднімання, ділення. Оператор та операнди розділені пробілами, дужки не використовуються.

Код програми консольного калькулятора математичних виразів

using System;
using System.Collections.Generic;
using System.Text;

class Program
{
    static void Main()
    {
        Console.OutputEncoding = Encoding.UTF8;
        Console.Write("Введіть вираз (приклад: \"2 + 3 * 5\"): ");
        var expression = Console.ReadLine();
        Console.WriteLine("{0} = {1}", expression, Calc(expression));
        Console.ReadLine();
    }

    /// <summary>
    /// Калькулятор виразів
    /// </summary>
    /// <param name="mathExpression">Математичний вираз</param>
    /// <returns></returns>
    static double Calc(string mathExpression)
    {
        var parts = mathExpression.Split(' '); //розбиваємо вираз на частини

        var operands = new List<double>();
        var operations = new List<string>();
        // в циклі розділяємо операнди та операції
        for (var i = 0; i < parts.Length; i += 2)
        {
            operands.Add(Convert.ToDouble(parts[i]));
            if (i + 1 < parts.Length)
            {
                operations.Add(parts[i + 1]);
            }
        }

        // передаємо в метод операції з однаковим приорітетом і функції для їх обчислення
        Calculate(operands, operations, "*", (a, b) => a * b, "/", (a, b) => a / b);
        Calculate(operands, operations, "+", (a, b) => a + b, "-", (a, b) => a - b);

        return operands[0]; //результат
    }

    /// <summary>
    /// Калькулятор для операцій з однаковим приорітетом
    /// </summary>
    /// <param name="operands">Список операндів</param>
    /// <param name="operations">Список операцій</param>
    /// <param name="currentOperation1">Поточна операція 1</param>
    /// <param name="function1">Функція для операції 1</param>
    /// <param name="currentOperation2">Поточна операція 2</param>
    /// <param name="function2">Функція для операції 2</param>
    static void Calculate(List<double> operands, List<string> operations, 
        string currentOperation1, Func<double, double, double> function1, 
        string currentOperation2, Func<double, double, double> function2)
    {
        while (true)
        {
            // шукаємо індекси поточних операцій
            var i1 = operations.IndexOf(currentOperation1);
            var i2 = operations.IndexOf(currentOperation2);

            int index; // індекс операції яку будемо обчислювати
            if (i1 >= 0 && i2 >= 0)
            {
                index = Math.Min(i1, i2);
            }
            else
            {
                index = Math.Max(i1, i2);
            }

            // якщо операцій в списку нема - виходимо з циклу
            if (index < 0)
            {
                break;
            }

            // обчислення поточної операції
            if (index == i1)
            {
                operands[index] = function1(operands[index], operands[index + 1]);
            }
            else
            {
                operands[index] = function2(operands[index], operands[index + 1]);
            }
            // видалення операції
            operations.RemoveAt(index);
            // видалення операнда
            operands.RemoveAt(index + 1);
        }
    }
}

Дивіться також: