Conversation
…ated class which ran method calculate (calculate an postfix expression's value), added test class
| public interface IStack | ||
| { | ||
| public Tuple<bool, double> Calculate(string expression); | ||
| } No newline at end of file |
There was a problem hiding this comment.
Стек - это структура данных, calculate она не умеет. Зато умеет push и pop :) Переделайте, методы интерфейса, пожалуйста
| { | ||
| return new Tuple<bool, double>(false, 0); | ||
| } | ||
| var parsedOperands = expression.Split(' '); |
There was a problem hiding this comment.
Можно просто Split(). Он тоже по пробелам разбивает
| { | ||
| return new Tuple<bool, double>(false, 0); | ||
| } | ||
| return new Tuple<bool, double>(true, stack[0]); |
There was a problem hiding this comment.
Метода Calculate в стеке быть не должно. Стек только знает как данные складывать и отдавать: по принципу first in last out.
А вот калькулятор должен реализовывать логику выполнения арифметических операций через стек, то есть используя его методы Push и Pop
|
|
||
| public class StackBasedOnList : IStack | ||
| { | ||
| private static readonly double Delta = 0.00001; |
There was a problem hiding this comment.
Аналогично, поля в C# со строчной буквы именуются
| if (!Test.TestStackImplementation()) | ||
| { | ||
| Console.WriteLine("Test has been failed"); | ||
| return; | ||
| } | ||
| Console.WriteLine("To choose a stack based on array press 1\nTo choose a stack based on list press 2\n"); | ||
| var isCorrect = Int32.TryParse(Console.ReadLine(), out var option); | ||
| if (!isCorrect) | ||
| { | ||
| Console.WriteLine("Not a number"); | ||
| return; | ||
| } | ||
|
|
||
| if (option > 2 || option < 1) | ||
| { | ||
| Console.WriteLine("Not an option"); | ||
| return; | ||
| } | ||
| StackCalculator calculator; | ||
| if (option == 1) | ||
| { | ||
| var stackArray = new StackBasedOnArray(); | ||
| calculator = new StackCalculator(stackArray); | ||
| } | ||
| else | ||
| { | ||
| var stackList = new StackBasedOnList(); | ||
| calculator = new StackCalculator(stackList); | ||
| } | ||
| Console.WriteLine("enter the expression to calculate:\n"); | ||
| var expression = Console.ReadLine(); | ||
| var result = (expression != null) ? calculator.Calculate(expression) : new Tuple<bool, double>(false, 0); | ||
| if (result.Item1 == false) | ||
| { | ||
| Console.WriteLine("An expression is incorrect"); | ||
| return; | ||
| } | ||
| Console.WriteLine("A result is {0}", result.Item2); No newline at end of file |
There was a problem hiding this comment.
Сместите все, пожалуйста, на 4 пробела влево
| { | ||
| return new Tuple<bool, double>(false, 0); | ||
| } | ||
| var parsedOperands = expression.Split(' '); |
There was a problem hiding this comment.
Тут тоже можно просто Split()
| stack.Add(product); | ||
| break; | ||
| case "/": | ||
| if (Math.Abs(stack[size - 1] - 0.0) < Delta) |
There was a problem hiding this comment.
Можно просто Math.Abs(stack[size - 1]) < Delta
| { | ||
| private static readonly double Delta = 0.00001; | ||
| private static readonly string[] TestCasesTrue = new[] { "12 8 - 3 *", "-4 9 + 8 * 4 /" }; | ||
| private static readonly double[] CorrectAnswers = new[] { 12.0, 10.0 }; |
There was a problem hiding this comment.
Опять же, все поля нужно именовать со строчной буквы
|
|
||
| public class StackBasedOnArray : IStack | ||
| { | ||
| private static readonly double Delta = 0.00001; |
There was a problem hiding this comment.
А поля с маленькой буквы нужно именовать
|
|
||
| public double? Pop(); | ||
|
|
||
| public int Size(); |
There was a problem hiding this comment.
Уже гораздо лучше, но все же стандартный интерфейс стека не предполагает того, что стек свой размер знает :)
У стека в его классическом понимании есть указатель на top. На этом факте строятся все операции по работе со стеком. Поэтому вы вполне можете добавить операцию IsEmpty по проверке стека на пустоту и Peek, чтобы "подсмотреть" значение вершины, не извлекая ее. Если конечно вам эти операции могут быть полезны. И на этом в общем-то все
| { | ||
| public void Push(double value); | ||
|
|
||
| public double? Pop(); |
There was a problem hiding this comment.
null возвращать не очень хорошо. Правильным поведением было бы выкинуть исключение в случае если пользователь пытается сделать Pop на пустом стеке. И в следующих домашках от вас это и будет ожидаться :)
Но так как выполняя эту домашку вы не обязаны были знать про исключения, то окей, пусть будет так
| public int Size() => stack.GetLength(0); | ||
|
|
There was a problem hiding this comment.
Опять-таки, метод Size стек не должен предоставлять пользователю.
У вас массив одномерный, можно было просто Length вместо GetLength(0)
| public StackElement(double value) | ||
| { | ||
| this.next = null; | ||
| this.value = value; | ||
| } | ||
|
|
||
| public StackElement(double value, StackElement? head) | ||
| { | ||
| this.next = head; | ||
| this.value = value; | ||
| } | ||
|
|
||
| public double Value | ||
| { | ||
| get => value; | ||
| set => this.value = value; | ||
| } | ||
|
|
||
| public StackElement? Next | ||
| { | ||
| get => next; | ||
| } | ||
| } |
There was a problem hiding this comment.
Кажется, что можно обойтись без этого класса :) Он вам нужен исключительно для того, чтобы знать про next элемент.
В массиве у вас элементы лежат подряд, и вы можете получить информацию о том, кто следующий за top. Так что давайте выполнять операции над стеком на массиве из double-ов
| private class StackElement | ||
| { | ||
| private double value; | ||
|
|
||
| private StackElement? next; | ||
|
|
||
| public StackElement(double value) | ||
| { | ||
| this.next = null; | ||
| this.value = value; | ||
| } | ||
|
|
||
| public StackElement(double value, StackElement? head) | ||
| { | ||
| this.next = head; | ||
| this.value = value; | ||
| } | ||
|
|
||
| public double Value | ||
| { | ||
| get => value; | ||
| } | ||
|
|
||
| public StackElement? Next | ||
| { | ||
| get => next; | ||
| } | ||
| } |
There was a problem hiding this comment.
Этот класс не нужен :)
Операции над стеком могут выражаться через операции над List. Например, Push(double element) в стек - это List.Add(double element). List.Add(double element) как раз-таки в конец списка элемент добавляет.
К тому же этот класс - копипаста :) Давайте как-то без копипасты
| { | ||
| if (expression.Length == 0) | ||
| { | ||
| return new Tuple<bool, double?>(false, null); |
There was a problem hiding this comment.
Здесь стоило бросить исключение, потому что пустой expression - это то, над чем мы не можем выполнить операцию Calculate. Но пусть будет так, потому что, опять же, выполняя эту домашку вы могли еще не знать про исключения
| _stack.Clear(); | ||
| } | ||
|
|
||
| public Tuple<bool, double?> Calculate(string expression) |
There was a problem hiding this comment.
А сюда могут null передать. Нужна проверка на то, что переданное значение не null
| @@ -0,0 +1,44 @@ | |||
| namespace HW2_Calculator; | |||
|
|
|||
| public static class Test | |||
There was a problem hiding this comment.
Не хватает еще тестов на реализации стеков, но это к следующей домашке относится, так что ок
| if (!Test.TestStackImplementation()) | ||
| { | ||
| Console.WriteLine("Test has been failed"); | ||
| return; | ||
| } | ||
| Console.WriteLine("To choose a stack based on array press 1\nTo choose a stack based on list press 2\n"); | ||
| var isCorrect = Int32.TryParse(Console.ReadLine(), out var option); | ||
| if (!isCorrect) | ||
| { | ||
| Console.WriteLine("Not a number"); | ||
| return; | ||
| } | ||
|
|
||
| if (option > 2 || option < 1) | ||
| { | ||
| Console.WriteLine("Not an option"); | ||
| return; | ||
| } | ||
| StackCalculator calculator; | ||
| if (option == 1) | ||
| { | ||
| var stackArray = new StackBasedOnArray(); | ||
| calculator = new StackCalculator(stackArray); | ||
| } | ||
| else | ||
| { | ||
| var stackList = new StackBasedOnList(); | ||
| calculator = new StackCalculator(stackList); | ||
| } | ||
| Console.WriteLine("enter the expression to calculate:\n"); | ||
| var expression = Console.ReadLine(); | ||
| var result = (expression != null) ? calculator.Calculate(expression) : new Tuple<bool, double?>(false, 0); | ||
| if (result.Item1 == false) | ||
| { | ||
| Console.WriteLine("An expression is incorrect"); | ||
| return; | ||
| } | ||
| Console.WriteLine("A result is {0}", result.Item2); No newline at end of file |
There was a problem hiding this comment.
Надо все на 4 пробела влево сместить
| { | ||
| return false; | ||
| } | ||
| if (Math.Abs((double)result.Item2 - CorrectAnswers[i]) > delta) |
There was a problem hiding this comment.
Обращайте внимание на warnings. В домашках их быть не должно :)
Поправьте, пожалуйста
No description provided.