-
Разработайте классы
Const
,Variable
,Add
,Subtract
,Multiply
,Divide
для вычисления выражений с одной переменной в типеint
(интерфейсExpression
), а такжеBigInteger
(интерфейсBigIntegerExpression
). -
Классы должны позволять составлять выражения вида
new Subtract(
new Multiply(
new Const(2),
new Variable("x")
),
new Const(3)
).evaluate(5)
При вычислении такого выражения вместо каждой переменной подставляется значение, переданное в качестве параметра методу evaluate
. Таким образом, результатом вычисления приведенного примера должно стать число 7.
- Метод
toString
должен выдавать запись выражения в полноскобочной форме. Например
new Subtract(
new Multiply(
new Const(2),
new Variable("x")
),
new Const(3)
).toString()
должен выдавать ((2 * x) - 3).
- Сложный вариант. Метод
toMiniString
(интерфейсToMiniString
) должен выдавать выражение с минимальным числом скобок. Например
new Subtract(
new Multiply(
new Const(2),
new Variable("x")
),
new Const(3)
).toMiniString()
должен выдавать 2 * x - 3.
- Реализуйте метод equals, проверяющий, что два выражения совпадают. Например,
new Multiply(new Const(2), new Variable("x"))
.equals(new Multiply(new Const(2), new Variable("x")))
должно выдавать true, а
new Multiply(new Const(2), new Variable("x"))
.equals(new Multiply(new Variable("x"), new Const(2)))
должно выдавать false.
- Для тестирования программы должен быть создан класс
Main
, который вычисляет значение выражения x*x−2*x+1, для x, заданного в командной строке. При выполнении задания следует обратить внимание на:
- Выделение общего интерфейса создаваемых классов.
- Выделение абстрактного базового класса для бинарных операций.
- Доработайте предыдущую задачу, так чтобы выражение строилось по записи вида x * (x - 2)*x + 1
- В записи выражения могут встречаться:
- бинарные операции: умножение *, деление /, сложение + и вычитание -;
- унарный минус
-
; - переменные
x
,y
иz
; - целочисленные константы в десятичной системе счисления, помещающиеся в 32-битный знаковый целочисленный тип;
- круглые скобки для явного обозначения приоритета операций;
- произвольное число пробельных символов в любом месте, не влияющем на однозначность понимания формулы (например, между операцией и переменной, но не внутри констант).
- Приоритет операций, начиная с наивысшего
- унарный минус;
- умножение и деление;
- сложение и вычитание.
- Разбор выражений рекомендуется производить методом рекурсивного спуска.
- Алгоритм должен работать за линейное время.
- Лексический анализ (токенизация) не требуется.
- Дополнительно реализуйте:
- бинарные операции (максимальный приоритет):
**
– возведение в степень,2 ** 3
равно 8;//
– логарифм,10 // 2
равно 3.
- бинарные операции (минимальный приоритет):
min
– минимум,2 min 3
равно 2;max
– максимум,2 max 3
равно 3.
- унарную операцию
abs
– модуль числа,abs -5
равно 5.
- унарные операции
l0
– число старших нулевых бит,l0 123456
равно 15;t0
– число младших нулевых бит,t0 123456
равно 6.
- бинарные операции (максимальный приоритет):
- Добавьте в программу, вычисляющую выражения, обработку ошибок, в том числе:
- ошибки разбора выражений;
- ошибки вычисления выражений.
Классы CheckedAdd
, CheckedSubtract
, CheckedMultiply
, CheckedDivide
и CheckedNegate
- Для выражения 1000000xxxx*x/(x-1) вывод программы должен иметь следующий вид:
x f
0 0
1 division by zero
2 32000000
3 121500000
4 341333333
5 overflow
6 overflow
7 overflow
8 overflow
9 overflow
10 overflow
Результат division by zero (overflow) означает, что в процессе вычисления произошло деление на ноль (переполнение).
- При выполнении задания следует обратить внимание на дизайн и обработку исключений.
- Человеко-читаемые сообщения об ошибках должны выводиться на консоль.
- Программа не должна «вылетать» с исключениями (как стандартными, так и добавленными).