Это простой калькулятор. Он выполняет расчеты. Однако каждый раз, когда он вычисляет, я сохраняю эту сумму и добавляю ее к промежуточной сумме. Но когда я набираю отмену, промежуточный итог исчезает, а предыдущий расчет не вычитается из промежуточного итога. Кто-нибудь может мне помочь? Это должно быть в формате сувенира. Поэтому, когда я отменяю, удаляется стек или сумма из предыдущего расчета. Я борюсь с этим.
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;
}
В вашей функции Undo вы просто возвращаете значение total, не выполняя с ним никаких манипуляций... Что, как вы ожидали, произойдет?
Can someone help me?
— это не вопрос программирования. Как бы то ни было, ваш код, похоже, не реализует UnDo, и, похоже, он знает об этом. Я предполагаю, что ваш стек будет хранить последнее действие? Если это так, вам нужно будет хранить больше, чем двойное значение - вам также нужно сохранить последнее предпринятое действие, чтобы вы знали, как применить значение, нет?
Почему бы просто не сделать result.Clear()
вместо того, чтобы снимать все предметы по отдельности? Вы слишком усложняете это, если только я ничего не упускаю.
Здесь нужно исправить пару вещей.
Во-первых, вы никогда ничего не присваиваете 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
. В противном случае какой смысл использовать стек, если вы не собираетесь использовать его там, где это имеет смысл?
Ваша команда отмены не пытается ничего удалить, так что....