# Convert roman numerals

• 11-18-2008, 04:41 AM
matzahboy
Convert roman numerals
I made a program to simplify roman numerals (projecteuler.net/index.php?section=problems&id=89]Problem 89 - Project Euler). I think that my method works, but I'm not sure if it is the most efficient method. Is there a way to shorten it and improve the time it takes to run it? Here's my code:

Code:

```/*  Converts Roman Numerals  */    import java.io.*; import java.util.Scanner; public class Problem_89 {             public static String westernToRoman(int western) {             int level=7;             String roman = "";             while(level>0) {                     if(western - levelToValue(level)>=0) {                             roman += String.valueOf(levelToNumeral(level));                             western -= levelToValue(level);                     } else {                             //Check to see if you should use subtraction                             int subtractorLevel = (int)Math.floor(level/2)*2-1;                             if(subtractorLevel>0 && western-(levelToValue(level)-levelToValue(subtractorLevel))>=0) {                                     western -= (levelToValue(level)-levelToValue(subtractorLevel));                                     roman = roman + levelToNumeral(subtractorLevel) + levelToNumeral(level);                             }                             level--;                                                         }             }             return roman;     }         public static int romanToWestern(String roman) {                         int western = 0; //the numerical version             char currentChar;             char nextChar;                         int i=0;                         while(i<roman.length()) {                     currentChar = roman.charAt(i);                     if(i<roman.length()-1) {                             nextChar = roman.charAt(i+1);                             if(getValue(currentChar)<getValue(nextChar)) {                                     western += (getValue(nextChar) - getValue(currentChar));                                     i+=2;                             } else {                                     western += getValue(currentChar);                                     i++;                             }                     } else {                             western += getValue(currentChar);                             i++;                     }             }             return western;                 }         private static int getValue(char l) { //Converts the numeral to a number             String letter = String.valueOf(l);             if(letter.equalsIgnoreCase("I")) return 1;             if(letter.equalsIgnoreCase("V")) return 5;             if(letter.equalsIgnoreCase("X")) return 10;             if(letter.equalsIgnoreCase("L")) return 50;             if(letter.equalsIgnoreCase("C")) return 100;             if(letter.equalsIgnoreCase("D")) return 500;             if(letter.equalsIgnoreCase("M")) return 1000;             return 0;     }         private static char levelToNumeral(int level) {             String character;             if(level == 1)                     character = "I";             else if(level == 2)                     character = "V";             else if(level == 3)                     character = "X";             else if(level == 4)                     character = "L";             else if(level == 5)                     character = "C";             else if(level == 6)                     character = "D";             else if (level == 7)                     character = "M";             else                     character = "E";             return character.charAt(0);     }         private static int levelToValue(int level) {             if(level == 1)                     return 1;             if(level == 2)                     return 5;             if(level == 3)                     return 10;             if(level == 4)                     return 50;             if(level == 5)                     return 100;             if(level == 6)                     return 500;             if(level == 7)                     return 1000;             //error             System.out.println("Error in the getLevel sub. level = " + level);             return 1;     }         public static void main(String[] args) throws FileNotFoundException  {                         String[] numerals = new String[1000];             int charactersBefore=0;             int charactersAfter=0;                         //Read the txt file:             File fFile = new File("C:\\roman.txt");             Scanner scanner = new Scanner(fFile);             int i=0;             while ( scanner.hasNextLine() ){                 numerals[i] = scanner.nextLine();                 i++;             }                         String simplified;                         //Calculate "charactersBefore" and then simplify the numerals             for (i=0; i<1000; i++) {                     charactersBefore += numerals[i].length();                     int western = Problem_89.romanToWestern(numerals[i]);                     String roman = Problem_89.westernToRoman(western);                     charactersAfter += roman.length();                     System.out.println(numerals[i] + " becomes " + western + " which becomes " + roman);             }                         System.out.println("We gained " + (charactersBefore - charactersAfter) + " characters");     } }```
• 11-18-2008, 04:50 AM
Fubarable
The "best" way is the way that 1) works for you, 2) is reliable and testable, and 3) is understandable to you and to others.

so there are many best and efficient ways to do this. One way is like so:
Code:

```public enum Roman {   M(1000), CM(900), D(500), CD(400), C(100),   XC(90), L(50), XL(40), X(10), IX(9), V(5),   IV(4), I(1);   private int number;   private Roman(int number)   {     this.number = number;   }   public int getNumber()   {     return number;   }   public static String toRoman(int arabicInt)   {     StringBuilder result = new StringBuilder();     for (int i = 0; i < values().length; i++)     {       int termCount = arabicInt / values()[i].getNumber();       for (int j = 0; j < termCount; j++)       {         result.append(values()[i].toString());       }       arabicInt %= values()[i].getNumber();     }     return result.toString();   } }```
Code:

```public class TestRoman {   public static void main(String[] args)   {     System.out.println(Roman.toRoman(1975));     for (int i = 0; i < 400; i++)     {       // note empty string "" if int is 0       System.out.println(Roman.toRoman(i));     }   } }```
• 02-21-2010, 10:16 PM
ŖàΫ ỏƒ Ңόρę
I have to write this programe using While loop and if statement or switch

I don't have to use arrays

Can anyone explain me the idea ?
• 02-21-2010, 10:29 PM
Fubarable
Hey Ray, Why not first give it a try yourself -- it doesn't matter if it works or not, what matters most is that you make the attempt -- and let's see what results. Then if it doesn't work, come on back with your code and specific questions. Oh, and please post your question a new thread rather than stepping on someone else's. Since it's your question, it belongs in your thread. :)

Best of luck!
• 02-21-2010, 11:06 PM
ŖàΫ ỏƒ Ңόρę
Hi Fubarable

Thank u 4 ur response

Actually, I thought about it and I finally discovered it

As you said, I will post the question and the code that I wrote and I will ask one question

appreciate ur cooperation

:)