Неправильный вывод выражений (+ и -) из калькулятора (java, простые римские числа)

Суть калькулятора - выполнение выражений с числами от 1 до 10. как с римскими, так и с арабскими.

Проблема - при выполнении выражений сложения и вычитания выражения с римскими числами ведут себя очень странно, в то время, как умножение и деление вроде работает. Например выражение I + V выводит VV, вместо VI. А вычитание вообще упирается в "Неверные данные".

Я начинающий программист и поэтому некоторые моменты могу упустить, что видимо и сделал. Прошу Вашей помощи.

Ссылка на gits - https://gist.github.com/relizerel/5d55212b8e39a78b54d158661f3dbf51 (4 java файла в самом низу)

calculator_src_Arithmetic.java

public class Arithmetic {
    public static int addition(int first, int second) {
        return first + second;
    }
    public static int division(int first, int second) {
        return first / second;
    }
    public static int multiplication(int first, int second) {
        return first * second;
    }
    public static int substraction(int first, int second) {
        return first - second;
    }
}

calculator_src_Converter.java

import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;

public class Converter {
    private static final TreeMap<Integer, String> map = new TreeMap<Integer, String>();

    static {
        map.put(100, "C");
        map.put(90, "XC");
        map.put(50, "L");
        map.put(40, "XL");
        map.put(10, "X");
        map.put(9, "IX");
        map.put(5, "V");
        map.put(4, "IV");
        map.put(1, "I");
    }

    private static final List<String> roman = new ArrayList<String>();

    static {
        roman.add("Пустое значение");
        roman.add("I");
        roman.add("II");
        roman.add("III");
        roman.add("IV");
        roman.add("V");
        roman.add("VI");
        roman.add("VII");
        roman.add("VIII");
        roman.add("IX");
        roman.add("X");
    }

    public static String toRoman(int number) {
        int l = map.floorKey(number);
        if (number == l) {
            return map.get(number);
        }
        return map.get(l) + toRoman(number - 1);
    }

    public  static int toArabic(String number) {
        return roman.indexOf(number);
    }
}

calculator_src_Logic.java

public class Logic {
    public static void logic(String firstString, String arithmetic, String secondString) {
        int first = 0;
        int second = 0;
        int result = 0;

        boolean flag = false;
        try {
            first = Integer.parseInt(firstString);
            second = Integer.parseInt(secondString);
        } catch (Exception e) {
            try {
                first = Converter.toArabic(firstString);
                second = Converter.toArabic(secondString);
                flag = true;
            } catch (Exception el) {
                System.out.println("Введены неверные данные");
            }
        }
        if (first < 1 || first > 10 || second < 1 || second > 10) {
            System.out.println("Введены неверные данные");
            System.exit(0);
        }
        if (arithmetic.equals("+")) {
            result = Arithmetic.addition(first, second);
        }
        if (arithmetic.equals("/")) {
            result = Arithmetic.division(first, second);
        }
        if (arithmetic.equals("*")) {
            result = Arithmetic.multiplication(first, second);
        }
        if (arithmetic.equals("-")) {
            result = Arithmetic.substraction(first, second);
        }
        if (flag) {
            String roman = Converter.toRoman(result);
            System.out.println(roman);
        } else {
            System.out.println(result);
        }
    }
}

calculator_src_Start.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Start {
    public static void main(String[] args) throws IOException {
        System.out.println("Введите выражение. Аргументы и знак должны быть разделены пробелом");
        System.out.println("Программа принимает арабские и римские числа");
        System.out.println("Числа от 0 до 10 включительно и от I до X включительно");

        List<String> list = new ArrayList<String>();
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String input = reader.readLine();
        try {
            Collections.addAll(list, input.split(" ", 50));
            Logic.logic(list.get(0), list.get(1), list.get(2));
        } catch (Exception e) {
            System.out.println("Введены неверные данные");
        }
        System.exit(0);
    }
}

Ответы (1 шт):

Автор решения: Дмитрий

Немного подправил код, попробуйте так:

import java.io.IOException;
import java.util.Scanner;

public class Start {

    public static void main(String[] args) throws IOException {

        System.out.println("Введите выражение. Аргументы и знак должны быть разделены пробелом");
        System.out.println("Программа принимает арабские и римские числа");
        System.out.println("Числа от 0 до 10 включительно и от I до X включительно");

        try (Scanner sc = new Scanner(System.in)) {
            String result = new Calculator().calculate(sc.nextLine().trim().split(" "));
            System.out.println(result);
        } catch (Exception e) {
            System.out.println("Введены неверные данные");
        }

    }
    
}

public class Calculator {
    
    private final Converter converter;

    public Calculator() {
        this.converter = new Converter();
    }

    public String calculate(String [] args) {
        if (args.length!=3) throw new IllegalArgumentException();
        try {
            int result = calculate(Integer.parseInt(args[0]), Integer.parseInt(args[2]), args[1]);
            return String.valueOf(result);
        } catch (NumberFormatException e) {
                int result = calculate (converter.toArabic(args[0]), converter.toArabic(args[2]), args[1]);
                return converter.toRoman(result);
        }
    }
    
    private int calculate(int first, int second, String arithmetic) {
        if (first < 1 || first > 10 || second < 1 || second > 10) throw new IllegalArgumentException();
        switch (arithmetic) {
            case "+": return first + second;
            case "/": return first / second;
            case "*": return first * second;
            case "-": return first - second;
            default: throw new IllegalArgumentException();
        }
    }
    
}

import java.util.Map;
import java.util.TreeMap;
import java.util.HashMap;

public class Converter {

    private static final TreeMap<Integer, String> ARABIC = new TreeMap<>();
    static {
        ARABIC.put(100, "C");
        ARABIC.put(90, "XC");
        ARABIC.put(50, "L");
        ARABIC.put(40, "XL");
        ARABIC.put(10, "X");
        ARABIC.put(9, "IX");
        ARABIC.put(5, "V");
        ARABIC.put(4, "IV");
        ARABIC.put(1, "I");
    }

    private static final Map<String, Integer> ROMAN = new HashMap<>();
    static {
        ROMAN.put("I",1);
        ROMAN.put("II",2);
        ROMAN.put("III",3);
        ROMAN.put("IV",4);
        ROMAN.put("V",5);
        ROMAN.put("VI",6);
        ROMAN.put("VII",7);
        ROMAN.put("VIII",8);
        ROMAN.put("IX",9);
        ROMAN.put("X",10);
    }

    public String toRoman(int number) {        
        int n = ARABIC.floorKey(number);
        return number == n ? ARABIC.get(number) : ARABIC.get(n) + toRoman(number - n);
    }

    public int toArabic(String number) {
        return ROMAN.get(number);
    }
    
}
→ Ссылка