Reputation: 111
I am writing a program to add two roman numerals without converting to any bases. I have everything working except I am not sure how to check if my input String is a valid roman numeral or not.
These are the rules to check validity:
I have not really been able to make much progress with this step and don't have anything working yet. Any help would be great!
Upvotes: 1
Views: 5610
Reputation: 2882
Why not use regular expression:
boolean valid = word.matches("^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$");
Look at the post of paxdiablo: How do you match only valid roman numerals with a regular expression?
Upvotes: 9
Reputation: 111
This is what I have come up with based on my rules. Any thoughts on refactoring this to make it simpler?
public static boolean checkValidity (String s1, HashSet<Character> romanNumerals){
HashSet<Character> alreadyContained = new HashSet<Character>();
if (s1.length() == 1 && romanNumerals.contains(s1.charAt(0))){
return true;
}
int i = 0;
while (i < s1.length()){
if (s1.charAt(i) == 'M'){
if (alreadyContained.contains('M')){
return false;
}
int count = 1;
i++;
while (s1.charAt(i) == 'M'){
i++;
count++;
}
alreadyContained.add('M');
if (count >= 5){
return false;
}
}
else if (s1.charAt(i) == 'D'){
if (alreadyContained.contains('D')){
return false;
}
alreadyContained.add('D');
if (!alreadyContained.contains('M')){
alreadyContained.add('M');
}
i++;
if ((i < s1.length()) && (s1.charAt(i) == 'D')){
return false;
}
}
else if (s1.charAt(i) == 'L'){
if (alreadyContained.contains('L')){
return false;
}
alreadyContained.add('L');
if (!alreadyContained.contains('M')){
alreadyContained.add('M');
}
if (!alreadyContained.contains('D')){
alreadyContained.add('D');
}
if (!alreadyContained.contains('C')){
alreadyContained.add('C');
}
i++;
if ((i < s1.length()) && (s1.charAt(i) == 'L')){
return false;
}
}
else if (s1.charAt(i) == 'V'){
if (alreadyContained.contains('V')){
return false;
}
alreadyContained.add('V');
if (!alreadyContained.contains('M')){
alreadyContained.add('M');
}
if (!alreadyContained.contains('D')){
alreadyContained.add('D');
}
if (!alreadyContained.contains('C')){
alreadyContained.add('C');
}
if (!alreadyContained.contains('L')){
alreadyContained.add('L');
}
if (!alreadyContained.contains('X')){
alreadyContained.add('X');
}
i++;
if ((i < s1.length()) && (s1.charAt(i) == 'V')){
return false;
}
}
else if (s1.charAt(i) == 'C'){
if (alreadyContained.contains('C')){
return false;
}
int count = 1;
i++;
if ((i < s1.length()) &&(s1.charAt(i) == 'M' || s1.charAt(i) == 'D')){
i++;
}
else if (i < s1.length() && s1.charAt(i) == 'C'){
while ((i < s1.length()) && (s1.charAt(i) == 'C')){
i++;
count++;
}
}
alreadyContained.add('C');
if (!alreadyContained.contains('M')){
alreadyContained.add('M');
}
if (!alreadyContained.add('D')){
alreadyContained.add('D');
}
if (count >= 5){
return false;
}
}
else if (s1.charAt(i) == 'X'){
if (alreadyContained.contains('X')){
return false;
}
int count = 1;
i++;
if ((i < s1.length()) && (s1.charAt(i) == 'D' || s1.charAt(i) == 'M')){
return false;
}
while ((i < s1.length()) && s1.charAt(i) == 'X'){
i++;
count++;
}
alreadyContained.add('X');
if (count >= 5){
return false;
}
}
else if (s1.charAt(i) == 'I'){
if (alreadyContained.contains('I')){
return false;
}
alreadyContained.add('I');
i++;
int count = 1;
if ((i < s1.length()) && (s1.charAt(i) != 'I' && s1.charAt(i) != 'X' && s1.charAt(i) != 'V')){
return false;
}
else if (i < s1.length() && s1.charAt(i) == 'I'){
while (i < s1.length() && s1.charAt(i) == 'I'){
i++;
count++;
}
if (count >= 4){
return false;
}
}
}
else if (!romanNumerals.contains(s1.charAt(i))){
return false;
}
}
return true;
}
Upvotes: 1
Reputation: 521
Loop through each character in the string. Use a if conditions to check which character it is. Use the if conditions to check for the roman numeral rule violations in the adjacent characters to the selected character.
for(int i = 0; i < s.length(); i++){
if (s[i] == 'V'){
**Check if the character before of after is also 'V'. Then it is a violation
}
else if(s[i] == 'L'){
**Conditions for 'L' etc.
}
}
Upvotes: 1