-
Notifications
You must be signed in to change notification settings - Fork 19.9k
/
Copy pathRomanToInteger.java
91 lines (83 loc) · 2.73 KB
/
RomanToInteger.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
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
package com.thealgorithms.conversions;
import java.util.HashMap;
import java.util.Map;
/**
* A utility class to convert Roman numerals into integers.
*
* <p>Roman numerals are based on seven symbols given below:
* <ul>
* <li>I = 1</li>
* <li>V = 5</li>
* <li>X = 10</li>
* <li>L = 50</li>
* <li>C = 100</li>
* <li>D = 500</li>
* <li>M = 1000</li>
* </ul>
*
* <p>If a smaller numeral appears before a larger numeral, it is subtracted.
* Otherwise, it is added. For example:
* <pre>
* MCMXCIV = 1000 + (1000 - 100) + (100 - 10) + (5 - 1) = 1994
* </pre>
*/
public final class RomanToInteger {
private static final Map<Character, Integer> ROMAN_TO_INT = new HashMap<>() {
{
put('I', 1);
put('V', 5);
put('X', 10);
put('L', 50);
put('C', 100);
put('D', 500);
put('M', 1000);
}
};
private RomanToInteger() {
}
/**
* Converts a single Roman numeral character to its integer value.
*
* @param symbol the Roman numeral character
* @return the corresponding integer value
* @throws IllegalArgumentException if the symbol is not a valid Roman numeral
*/
private static int romanSymbolToInt(final char symbol) {
return ROMAN_TO_INT.computeIfAbsent(symbol, c -> { throw new IllegalArgumentException("Unknown Roman symbol: " + c); });
}
/**
* Converts a Roman numeral string to its integer equivalent.
* Steps:
* <ol>
* <li>Iterate over the string from right to left.</li>
* <li>For each character, convert it to an integer value.</li>
* <li>If the current value is greater than or equal to the max previous value, add it.</li>
* <li>Otherwise, subtract it from the sum.</li>
* <li>Update the max previous value.</li>
* <li>Return the sum.</li>
* </ol>
*
* @param roman the Roman numeral string
* @return the integer value of the Roman numeral
* @throws IllegalArgumentException if the input contains invalid Roman characters
* @throws NullPointerException if the input is {@code null}
*/
public static int romanToInt(String roman) {
if (roman == null) {
throw new NullPointerException("Input cannot be null");
}
roman = roman.toUpperCase();
int sum = 0;
int maxPrevValue = 0;
for (int i = roman.length() - 1; i >= 0; i--) {
int currentValue = romanSymbolToInt(roman.charAt(i));
if (currentValue >= maxPrevValue) {
sum += currentValue;
maxPrevValue = currentValue;
} else {
sum -= currentValue;
}
}
return sum;
}
}