Сложение римских чисел java

Калькулятор римских цифр 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» вернет ошибку)
Оцените статью