Лабораторная работа №2 Java Барлита. Алгоритм решения
Скачать 197.05 Kb.
|
Алгоритм решенияСоздадим абстрактный класс Number, который будет содержать закрытые поля с числом и с его текстовым представлением. Также определим в нём абстрактные методы для умножения, сложения, вычитания и деления. Классы NumberBit / NumberHex наследуют класс Number. Определим для каждого из производных классов закрытые статические поля: с шаблоном для проверки входной строки на корректность и с основанием системы счисления. Проверка на корректность производится при создании объекта класса. Входная строка после проверки преобразовывается в число, а если формат неверный, выбрасывается исключение. В консоли создадим цикл, в котором будет предлагаться ввести простое арифметическое выражение. Числа hex и binary определяются по префиксу 0x или 0b соответственно. Спецификация классовКласс Number public abstract Number Add(Number x) – для сложения public abstract Number Sub(Number x) – для вычитания public abstract Number Mul(Number x) – для умножения public abstract Number Div(Number x) – для деления public String toString() – вывод числа в исходной системе счисления Классы NumberBit / NumberHex public Number Add(Number x) – для сложения public Number Sub(Number x) – для вычитания public Number Mul(Number x) – для умножения public Number Div(Number x) – для деления public String Prefix() – вывод префикса системы счисления Диаграмма классовДиаграмма представлена на рисунке 1: Рисунок 1 - Диаграмма классов Листинг программыMain.java package lab2; import java.util.Scanner; public class Main { public static void main(String[] args) { System.out.println("Hello world!"); Scanner scanner = new Scanner(System.in); char[] operands = new char[] {'+', '-', '*', '/' }; while (true) { System.out.println("Введите простое арифметическое выражение (q - выход):"); System.out.println("Формат ввода: [0x или 0b]число, операнды: [+-*/]"); String response = scanner.nextLine(); if (response.equalsIgnoreCase("q")) { scanner.close(); return; } int operandPos = -1; char operand = '?'; //Ищем операнд в строке for (int j = 0; j < operands.length; j++) { operand = operands[j]; operandPos = response.indexOf(operand); if (operandPos != -1) break; } if (operandPos < 1) { System.out.println("Операнд не найден или не поддерживается"); continue; } //Копируем числа в две переменные String s1 = response.substring(0, operandPos).trim(); String s2 = response.substring(operandPos + 1, response.length()).trim(); Number a, b, x = null; //Преобразовываем строки в объекты, если это возможно try { if (s1.startsWith(NumberBit.Prefix())) a = new NumberBit(s1.substring(NumberBit.Prefix().length())); else if (s1.startsWith(NumberHex.Prefix())) a = new NumberHex(s1.substring(NumberHex.Prefix().length())); else { System.out.println("Неизвестный формат первого числа"); continue; } if (s2.startsWith(NumberBit.Prefix())) b = new NumberBit(s2.substring(NumberBit.Prefix().length())); else if (s2.startsWith(NumberHex.Prefix())) b = new NumberHex(s2.substring(NumberHex.Prefix().length())); else { System.out.println("Неизвестный формат второго числа"); continue; } } catch (NumberFormatException ex) { System.out.println(ex.getMessage()); continue; } //Выполняем заданную операцию switch (operand) { case '+': x = a.Add(b); break; case '-': x = a.Sub(b); break; case '*': x = a.Mul(b); break; case '/': try { x = a.Div(b); } catch (ArithmeticException ex) { System.out.println(ex.getMessage()); continue; } break; } //Выводим результат if (x != null) { if (x instanceof NumberBit) System.out.print(NumberBit.Prefix()); else if (x instanceof NumberHex) System.out.print(NumberHex.Prefix()); System.out.println(x); } } } } Number.java package lab2; public abstract class Number { protected String value; protected int vInt; protected final static String divExc = "Деление на ноль"; public Number(String value) { this.value = value; } public abstract Number Add(Number x); public abstract Number Sub(Number x); public abstract Number Mul(Number x); public abstract Number Div(Number x); @Override public String toString() { return value; } } NumberBit.java package lab2; import java.util.regex.Pattern; public class NumberBit extends Number { private final static Pattern regex = Pattern.compile("[^01]+"); private final static String errorMsg = "Представлено не двоичное число"; private final static int radix = 2; public NumberBit(String value) throws NumberFormatException { super(value); if (regex.matcher(value).find() || value.length() == 0) throw new NumberFormatException(errorMsg); vInt = Integer.parseInt(value, radix); } @Override public Number Add(Number x) { int v = vInt + x.vInt; return new NumberBit(Integer.toBinaryString(v)); } @Override public Number Sub(Number x) { int v = vInt - x.vInt; return new NumberBit(Integer.toBinaryString(v)); } @Override public Number Mul(Number x) { int v = vInt * x.vInt; return new NumberBit(Integer.toBinaryString(v)); } @Override public Number Div(Number x) throws ArithmeticException { if (x.vInt == 0) throw new ArithmeticException(divExc); int v = vInt / x.vInt; return new NumberBit(Integer.toBinaryString(v)); } public static String Prefix() { return "0b"; } } NumberHex.java package lab2; import java.util.regex.Pattern; public class NumberHex extends Number { private final static Pattern regex = Pattern.compile("[^\\da-fA-F]+"); private final static String errorMsg = "Представлено не шестнадцатиричное число"; private final static int radix = 16; public NumberHex(String value) throws NumberFormatException { super(value); if (regex.matcher(value).find() || value.length() == 0) throw new NumberFormatException(errorMsg); vInt = Integer.parseInt(value, radix); } @Override public Number Add(Number x) { int v = vInt + x.vInt; return new NumberHex(Integer.toHexString(v)); } @Override public Number Sub(Number x) { int v = vInt - x.vInt; return new NumberHex(Integer.toHexString(v)); } @Override public Number Mul(Number x) { int v = vInt * x.vInt; return new NumberHex(Integer.toHexString(v)); } @Override public Number Div(Number x) throws ArithmeticException { if (x.vInt == 0) throw new ArithmeticException(divExc); int v = vInt / x.vInt; return new NumberHex(Integer.toHexString(v)); } public static String Prefix() { return "0x"; } } Результаты тестированияПример сложения и вычитания показан на рисунке 2: Рисунок 2 – Сложение и вычитание Пример умножения чисел показан на рисунке 3: Рисунок 3 – Умножение Пример деления показан на рисунке 4: Рисунок 4 – Деление чисел Проверка на некорректный ввод продемонстрирована на рисунке 5: Рисунок 5 – Некорректный ввод |