- Калькулятор римских цифр java
- Преобразование между римскими и арабскими цифрами в Java
- 2. Римские цифры
- 3. Модель
- 4. С римского на арабский
- 4.1. Реализация
- 4.2. Тест
- 5. с арабского на романский
- 5.1. Реализация
- 5.2. Тест
- 6. Заключение
- Saved searches
- Use saved searches to filter your results more quickly
- Xubunter/Calculator
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
Калькулятор римских цифр java
но при запуске калькулятор не работает, не могли бы подсказать в чем проблема?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
import java.util.Scanner; public class Calculator { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); startCalc(); while (true) { System.out.println("Input: "); String line = scanner.nextLine(); if (line.equals("exit")) { exitCalc(); break; } try { String[] symbols = line.split(" "); if (symbols.length != 3) throw new Exception("Что-то пошло не так, попробуйте еще раз"); Number firstNumber = NumberService.parseAndValidate(symbols[0]); Number secondNumber = NumberService.parseAndValidate(symbols[2], firstNumber.getType()); String result = ActionService.calculate(firstNumber, secondNumber, symbols[1]); System.out.println("Output: \n" + result); } catch (Exception e) { System.out.println(e.getMessage()); exitCalc(); break; } } scanner.close(); } private static void startCalc() { System.out.println("Добро пожаловать в Калькулятор 1.1, он работает только с арабскими и римскими цифрами от 1 до 10"); System.out.println("Обладает довольно скудным фукционалом и может предложить только следующие операции:"); System.out.println("Сложение(+), Вычитание(-), Умножение(*), Деление(/)"); System.out.println("Если Вы хотите покинуть программу, введите 'exit'"); } private static void exitCalc() { System.out.println("До скорых встреч!"); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
public class ActionService { public static String calculate(Number first, Number second, String action) throws Exception { int result; switch (action) { case "+": result = first.getValue() + second.getValue(); break; case "-": result = first.getValue() - second.getValue(); break; case "*": result = first.getValue() * second.getValue(); break; case "/": result = first.getValue() / second.getValue(); break; default: throw new Exception("Не правильно введен символ операции, используйте только +, -, *, /"); } if (first.getType() == NumberType.ROMAN) { return NumberService.toRomanNumber(result); } else return String.valueOf(result); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
import java.util.Map; import java.util.TreeMap; class NumberService { private final static TreeMap Integer, String > romanString = new TreeMap<>(); static { romanString.put(1, "I"); romanString.put(4, "IV"); romanString.put(5, "V"); romanString.put(9, "IX"); romanString.put(10, "X"); romanString.put(40, "XL"); romanString.put(50, "L"); romanString.put(90, "XC"); romanString.put(100, "C"); } static Number parseAndValidate(String symbol) throws Exception { int value; NumberType type; try { value = Integer.parseInt(symbol); type = NumberType.ARABIC; }catch (NumberFormatException e) { value = toArabicNumber(symbol); type = NumberType.ROMAN; } if (value 1 || value > 10) { throw new Exception("Неподходящее значение числа(ел), используйте числа от 1 до 10 включительно"); } return new Number(value, type); } static Number parseAndValidate(String symbol, NumberType type) throws Exception { Number number = parseAndValidate(symbol); if (number.getType() != type) { throw new Exception("Числа разных типов, используйте один тип вводных значений"); } return number; } private static int letterToNumber(char letter) { int result = -1; for (Map.Entry Integer, String > entry: romanString.entrySet()) { if (entry.getValue().equals(String.valueOf(letter))) result = entry.getKey(); } return result; } static String toRomanNumber(int number) { int i = romanString.floorKey(number); if (number == i) { return romanString.get(number); } return romanString.get(i) + toRomanNumber(number - i); } static int toArabicNumber(String roman) throws Exception { int result = 0; int i = 0; while (i roman.length()) { char letter = roman.charAt(i); int num = letterToNumber(letter); if (num 0) throw new Exception("Неверный римский символ"); i++; if (i == roman.length()) { result += num; }else { int nextNum = letterToNumber(roman.charAt(i)); if(nextNum > num) { result += (nextNum - num); i++; } else result += num; } } return result; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class Number { private int value; private NumberType type; Number(int value, NumberType type) { this.value = value; this.type = type; } int getValue() { return value; } NumberType getType() { return type; } }
public enum NumberType { ARABIC, ROMAN }
Преобразование между римскими и арабскими цифрами в Java
Древние римляне разработали собственную систему счисления, называемую римскими цифрами. Система использует буквы с разными значениями для представления чисел. Римские цифры до сих пор используются в некоторых второстепенных приложениях.
В этом уроке мы реализуем простые преобразователи, которые будут преобразовывать числа из одной системы в другую.
2. Римские цифры
В римской системе у нас есть 7 символов, которые представляют числа :
- я представляю 1
- V представляет 5
- Х представляет 10
- L представляет 50
- С представляет 100
- D представляет 500
- М представляет 1000
Первоначально люди представляли 4 с IIII или 40 с XXXX. Это может быть довольно неудобно читать. Также легко принять четыре символа рядом друг с другом за три символа.
Римские цифры используют вычитающую запись , чтобы избежать таких ошибок. Вместо того, чтобы говорить « четыре раза один » (IIII), можно сказать, что на один меньше пяти (IV).
Насколько это важно с нашей точки зрения? Это важно, потому что вместо простого сложения чисел символ за символом нам может потребоваться проверить следующий символ, чтобы определить, нужно ли прибавлять или вычитать число.
3. Модель
Давайте определим перечисление для представления римских цифр:
enum RomanNumeral I(1), IV(4), V(5), IX(9), X(10), XL(40), L(50), XC(90), C(100), CD(400), D(500), CM(900), M(1000); private int value; RomanNumeral(int value) this.value = value; > public int getValue() return value; > public static ListRomanNumeral> getReverseSortedValues() return Arrays.stream(values()) .sorted(Comparator.comparing((RomanNumeral e) -> e.value).reversed()) .collect(Collectors.toList()); > >
Обратите внимание, что мы определили дополнительные символы, чтобы помочь с вычитающей записью. Мы также определили дополнительный метод с именем getReverseSortedValues() .
Этот метод позволит нам явно получить определенные римские цифры в порядке убывания значения.
4. С римского на арабский
Римские цифры могут представлять только целые числа от 1 до 4000 . Мы можем использовать следующий алгоритм для преобразования римской цифры в арабскую (перебор символов в обратном порядке от M до I ):
LET numeral be the input String representing an Roman Numeral LET symbol be initialy set to RomanNumeral.values()[0] WHILE numeral.length > 0: IF numeral starts with symbol's name: add symbol's value to the result remove the symbol's name from the numeral's beginning ELSE: set symbol to the next symbol
4.1. Реализация
Далее мы можем реализовать алгоритм на Java:
public static int romanToArabic(String input) String romanNumeral = input.toUpperCase(); int result = 0; ListRomanNumeral> romanNumerals = RomanNumeral.getReverseSortedValues(); int i = 0; while ((romanNumeral.length() > 0) && (i romanNumerals.size())) RomanNumeral symbol = romanNumerals.get(i); if (romanNumeral.startsWith(symbol.name())) result += symbol.getValue(); romanNumeral = romanNumeral.substring(symbol.name().length()); > else i++; > > if (romanNumeral.length() > 0) throw new IllegalArgumentException(input + " cannot be converted to a Roman Numeral"); > return result; >
4.2. Тест
Наконец, мы можем протестировать реализацию:
@Test public void given2018Roman_WhenConvertingToArabic_ThenReturn2018() String roman2018 = "MMXVIII"; int result = RomanArabicConverter.romanToArabic(roman2018); assertThat(result).isEqualTo(2018); >
5. с арабского на романский
Мы можем использовать следующий алгоритм для преобразования арабских цифр в римские (перебирая символы в обратном порядке от M до I ):
LET number be an integer between 1 and 4000 LET symbol be RomanNumeral.values()[0] LET result be an empty String WHILE number > 0: IF symbol's value append the result with the symbol's name subtract symbol's value from number ELSE: pick the next symbol
5.1. Реализация
Теперь мы можем реализовать алгоритм:
public static String arabicToRoman(int number) if ((number 0) || (number > 4000)) throw new IllegalArgumentException(number + " is not in range (0,4000]"); > ListRomanNumeral> romanNumerals = RomanNumeral.getReverseSortedValues(); int i = 0; StringBuilder sb = new StringBuilder(); while ((number > 0) && (i romanNumerals.size())) RomanNumeral currentSymbol = romanNumerals.get(i); if (currentSymbol.getValue() number) sb.append(currentSymbol.name()); number -= currentSymbol.getValue(); > else i++; > > return sb.toString(); >
5.2. Тест
Наконец, мы можем протестировать реализацию:
@Test public void given1999Arabic_WhenConvertingToRoman_ThenReturnMCMXCIX() int arabic1999 = 1999; String result = RomanArabicConverter.arabicToRoman(arabic1999); assertThat(result).isEqualTo("MCMXCIX"); >
6. Заключение
В этой быстрой статье мы показали, как конвертировать римские и арабские цифры.
Мы использовали перечисление для представления набора римских цифр и создали служебный класс для выполнения преобразований.
Полную реализацию и все тесты можно найти на GitHub .
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Xubunter/Calculator
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
Тестовая задача Java Mentor
- Обработка римских и арабских чисел
- Доступны операции сложения, вычитания, умножения и деления
- Пробелы между символами не влияют на результат
- Вывод ошибки при некорректном вводе
- Диапазон доступных чисел для ввода и вывода от 1 до 10 включительно
- Одновременная обработка чисел только одного вида (Запись вида «3 + IV» вернет ошибку)
- Calculator
- public static String calc(String inp) — возвращает результат вычислений из входной строки с учетом вида числе (для римских чисел ответ вернется так же римским числом)
- public static boolean isOperation(char c) — проверка на соответствие доступным математическим операциям
- public static boolean isValidNumber(int num) — проверка на принадлежность диапазону от 1 до 10
- public int getNumber() — возвращает соответствующее арабское число
- public static RomanNumber toRoman(int num) — возвращает римское число, соответствующее арабскому
- public static RomanNumber toRoman(String str) — возвращает римское число, соответствующее его строковому представлению
- оставшиеся методы стравнения и математических операций не используются
- При работе с арабскими, числами запись «1++1» не будет ошибочной («+1» парсится в «1» и запись «1+1» является корректной)
- Ввод вида «-1+1″ вернет ошибку указывающую на пустое значение », вместо ‘-1’ (Первым вхождением находится допустимая операция «-» и строка делится на три части, но первая часть пустая, вторая — «-«, третья — «1+1»)
- Пробел между числами не приведет к ошибке («I II + VI» конвертируется в «III+VI»);