Чтобы отменить вычисление и вычесть его из промежуточного итога

Это простой калькулятор. Он выполняет расчеты. Однако каждый раз, когда он вычисляет, я сохраняю эту сумму и добавляю ее к промежуточной сумме. Но когда я набираю отмену, промежуточный итог исчезает, а предыдущий расчет не вычитается из промежуточного итога. Кто-нибудь может мне помочь? Это должно быть в формате сувенира. Поэтому, когда я отменяю, удаляется стек или сумма из предыдущего расчета. Я борюсь с этим.

 class Calculator
 {
    public Stack<double> result= new Stack<double>();
    double total = 0;

    public void Add(double a, double b)
    {
        total += a + b;
        Console.WriteLine("Sum:{0}", total);
        result.Push(total);

    }
    public void Sub(double a, double b)
    {
        total += a - b;
        Console.WriteLine("Difference:{0}", total);
        result.Push(total);

    }
    public void Mul(double a, double b)
    {
        total += a * b;
        Console.WriteLine("Product:{0} ", total);
        result.Push(total);

    }
    public void Div(double a, double b)
    {
        if (b!=0)
        {
            total += a / b;
            Console.WriteLine("Quotient:{0}", total);
            result.Push(total);

        }
        else
        {
            Console.WriteLine("Error: Cannot divide by 0");
        }
    }

    double GetTotal()
    {
        return total;


    }
    void Undo()
    {
        if (result.Count==0)
        {
            Console.WriteLine("UNDO IS NOT AVAILABLE");
        }
        Console.WriteLine("Running total:{0}", total);

    }
    void clear()
    {
        while (result.Count !=0)
            result.Pop();
        total = 0;
        Console.WriteLine("Running total:{0}", total);
    }
    static int Main()
    {
        Calculator cal=new Calculator();
        string line = "";
        while (true)
        {
            Console.WriteLine("Enter (Clear, Undo, Exit, Expression):");

            if (line.ToLower() == "exit")
                break;
            else if (line.ToLower() == "undo")
                cal.Undo();
            else if (line.ToLower() == "clear")
                cal.clear();
            else
            {
                double a, b;

                Console.WriteLine("Write the first number");
                double.TryParse(Console.ReadLine(), out a);

                Console.WriteLine("Write the second number");
                double.TryParse(Console.ReadLine(), out b);

                Console.WriteLine("Write the operand (+, -, /, *)");
                char.TryParse(Console.ReadLine(), out char c);


                if (c == '+')
                    cal.Add(a, b);
                if (c == '-')
                    cal.Sub(a, b);
                if (c == '*')
                    cal.Mul(a, b);
                if (c == '/')
                    cal.Div(a, b);
            }
        }
        return 0;
    }

Ваша команда отмены не пытается ничего удалить, так что....

BugFinder 11.06.2019 15:25

В вашей функции Undo вы просто возвращаете значение total, не выполняя с ним никаких манипуляций... Что, как вы ожидали, произойдет?

InfiniteHigh 11.06.2019 15:25
Can someone help me? — это не вопрос программирования. Как бы то ни было, ваш код, похоже, не реализует UnDo, и, похоже, он знает об этом. Я предполагаю, что ваш стек будет хранить последнее действие? Если это так, вам нужно будет хранить больше, чем двойное значение - вам также нужно сохранить последнее предпринятое действие, чтобы вы знали, как применить значение, нет?
Ňɏssa Pøngjǣrdenlarp 11.06.2019 15:26

Почему бы просто не сделать result.Clear() вместо того, чтобы снимать все предметы по отдельности? Вы слишком усложняете это, если только я ничего не упускаю.

Code Stranger 11.06.2019 16:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
88
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь нужно исправить пару вещей.

Во-первых, вы никогда ничего не присваиваете line, поэтому ваш код сразу попадает в блок else для «Выражения». Так что не только Undo() не работает, но я не понимаю, как могут работать методы Clear() или Exit(). Что-то вроде этого поможет в этом, назначив line:

while (true)
{
    Console.WriteLine("Enter (Clear, Undo, Exit, Expression):");
    line = Console.ReadLine();

    if (line.ToLower() == "exit")
        break;

    //Rest of the code left out for simplicity...
}  

Обратите внимание, что это рассматривает недопустимый ввод как «Выражение» и false по пути else, поэтому вы можете рассмотреть возможность явной проверки line.ToLower() == "expression" и выдачи сообщения об ошибке в противном случае.

Также рассмотрите возможность перехода на оператор switch. Это ни в коем случае не требуется, но немного проще в обслуживании и чтении, IMO. Вам также, вероятно, следует сделать нечувствительный к регистру Equals()с этой перегрузкой, а не преобразовывать ввод в нижний регистр.

Что касается фактической реализации вашего метода Undo(), поскольку ваше последнее действие — всего один элемент ниже Stack, просто Pop() верхний элемент и Peek() в Stack для вашего предыдущего итога:

void Undo()
{
    if (result.Count==0)
    {
        Console.WriteLine("UNDO IS NOT AVAILABLE");
    }

    result.Pop(); //Remove current total from last expression
    total = result.Peek(); //Take previous total

    Console.WriteLine("Running total:{0}", total);
}  

Это должно помочь вам пройти большую часть пути. Это могут быть и другие вещи, которые вам также необходимо исправить. Я протестировал функции отмены и очистки, и они, похоже, работают, как и ожидалось, но ничего больше не проверял (кроме базовых выражений + и -).

Да, кажется вполне естественным использование Pop и Peek. В противном случае какой смысл использовать стек, если вы не собираетесь использовать его там, где это имеет смысл?

Code Stranger 11.06.2019 16:07

Другие вопросы по теме