Преобразование римских чисел в арабские

Всем Привет. Вообщем нужен код, чтобы преобразовывать римские числа в арабские. Смог нарыть вот такой код

   String[] roman = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "XI", "X"};
        Scanner reader = new Scanner(System.in);
        String number = reader.nextLine();
        
        for (int i = 0; i < 10; i++){
            if (roman[i].equals(number))
                System.out.println(i+1);

Проблема в том,что он работает только до 10. Как можно сделать, чтобы любое римское число могло преобразоваться? Не писать же массив до бесконечности))


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

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

Алгоритм достаточно простой, как, собственно, и реализация:

import java.util.function.BiFunction;
import java.util.LinkedHashMap;
import java.util.Map;

/*
I - 1
V - 5
X - 10
L - 50
C - 100
D - 500
M - 1000
*/
public class Roman {

    private final static String[] NUMB_1_9 = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};

    private final static Map<Integer, BiFunction <Integer, StringBuilder, StringBuilder>> MAP = new LinkedHashMap<>(6);
    static{
        MAP.put(1000, (number, sb) -> convert(number, "M", sb));
        MAP.put(500, (number, sb) -> sb.append(number == 4 ? "CM" : "D"));
        MAP.put(100, (number, sb) -> convert(number, "CD", "C", sb));
        MAP.put(50, (number, sb) -> sb.append(number == 4 ? "XC" : "L"));
        MAP.put(10, (number, sb) -> convert(number, "XL", "X", sb));
        MAP.put(1, (number, sb) -> sb.append(NUMB_1_9[number]));
    }

    public static String convert(int number) {
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < 10; i++) {
            
        }
        for (int numb : MAP.keySet()) {
            MAP.get(numb).apply(number / numb, sb);
            number %= numb;
        }
        return sb.toString();
    }

    private static StringBuilder convert(int number, String exclude, String include, StringBuilder sb) {
        if (number == 4) return sb.append(exclude);
        if (number != 0 && number < 4) return convert(number, include, sb);
        return sb;
    }

    private static StringBuilder convert(int number, String value, StringBuilder sb) {
        for (int i = 0; i < number; i++) sb.append(value);
        return sb;
    }

}
→ Ссылка
Автор решения: JavaFaraon

Есть такое очень простое решение

    public class Main {
    public static void main(String[] args) {
        new Main().run();
    }

    public void run() {
        Solution solution = new Solution();
        System.out.println("Result = " + solution.romanToInt(inputString()));
    }

    public String inputString() {
        System.out.println("Введите римское число в виде строки БОЛЬШИМИ БУКВАМИ");
        Scanner scan = new Scanner(System.in);
        String s;
        if (scan.hasNextLine()) {
            s = scan.nextLine();
            if (!Objects.equals(s, "")) {
              if (!isMatch(Pattern.compile("^(M{0,3})(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$"), s)) {
                  System.out.println("Вы ввели число в неправильном формате");
                  return  inputString();
              } else System.out.println("Вы ввели " + s);
            } else {
                return inputString();
            }
        } else {
            return inputString();
        }
        return s;
    }

    public boolean isMatch(Pattern ptr, String str) {
        Matcher matcher = ptr.matcher(str);
        return matcher.find();
    }
 }

Class Solution

public class Solution {
    public int romanToInt(String s) {
        char [] chars = s.toLowerCase().toCharArray();
        int result = 0;
        int arabic = 0;
        int arabicPrevious = 0;
        Main main = new Main();
        for (int i = chars.length -1; i >= 0 ; i--) {
            switch (chars[i]) {
                case 'm' -> arabic = 1000;
                case 'd' -> arabic = 500;
                case 'c' -> arabic = 100;
                case 'l' -> arabic = 50;
                case 'x' -> arabic = 10;
                case 'v' -> arabic = 5;
                case 'i' -> arabic = 1;
                default -> {
                    System.out.println("Выражение ошибочно.");
                    main.inputString();
                }
            }
            if (arabic >= arabicPrevious) {
                result+=arabic;
            } else result-=arabic;
            arabicPrevious = arabic;
        }
        return result;
    }
}
→ Ссылка