Conversion from Roman to decimal numbers My program makes a conversion between Roman and decimal numbers. Can you give me some advice on how to make it look more readable or to improve in general?

Would code extraction of similar-looking logic from switch cases into helper methods do the job? Or can we take some other approach and use recursion, enums or regular expressions to solve the conversion task?

import java.util.Scanner;

public class Romans_to_Decimals 
{
    public static void main(String[] args) 
    {
    System.out.println("Enter roman number from I to MMMCMXCIX (1 to 3999), q to quit: ");
    Scanner in = new Scanner(System.in);

    boolean done = false;
    while (!done &amp;&amp; in.hasNext())
    {   
        String number = in.next();
        if (number.equals("q"))
        {
            done = true;
        }
        else
        {
            int result = 0;
            char[] array = number.toCharArray();

            for (int i = number.length() - 1; i &gt;= 0; i--)
            {
                switch (array[i])
                {
                case 'I': 
                        result += 1;   
                        break;
                case 'X': 
                        if (i != 0 &amp;&amp; array[i-1] == 'I')    //IX = 9
                        { 
                            result += 9;
                            i--;
                        } 
                        else
                        {
                            result += 10;
                        }
                        break;
                case 'C': 
                        if (i != 0 &amp;&amp; array[i-1] == 'X')    //XC = 90
                        { 
                            result += 90;
                            i--;
                        } 
                        else
                        {
                            result += 100;
                        }
                        break;
                case 'M': 
                        if (i != 0 &amp;&amp; array[i-1] == 'C')    //CM = 900
                        { 
                            result += 900;
                            i--;
                        } 
                        else
                        {
                            result += 1000;
                        }
                        break;
                case 'V': 
                        if (i != 0 &amp;&amp; array[i-1] == 'I')    //IV = 4 
                        { 
                            result += 4;
                            i--;
                        } 
                        else
                        {
                            result += 5;
                        }
                        break;
                case 'L':
                        if (i != 0 &amp;&amp; array[i-1] == 'X')    //XL = 40 
                        { 
                            result += 40;
                            i--;
                        } 
                        else
                        {
                            result += 50;
                        }
                        break;
                case 'D': 
                        if (i != 0 &amp;&amp; array[i-1] == 'C')    //CD = 400
                        { 
                            result += 400;
                            i--;
                        } 
                        else
                        {
                            result += 500;
                        }
                        break;  
                default:
                        System.out.println("Not correct roman number");
                        break;
                }
            }
            System.out.println("Corresponding decimal number is: " + result);
            }
        }
        in.close();
    }
}
public class Romans_to_Decimals



"when in Rome, do as the Romans do!"
keep to Java naming conventions when programming java.


for (int i = number.length() - 1; i &gt;= 0; i--)



use the fore each notation if possible. In your case this would require a different approach to the problem tough...


switch (array[i])
 //..
    if (i != 0 &amp;&amp; array[i-1] == 'I')



use variables with explicit names. 


 case 'X': 
                    if (i != 0 &amp;&amp; array[i-1] == 'I')    //IX = 9
                    { 
                        result += 9;
                        i--;
                    } 
                    else
                    {
                        result += 10;
                    }
                    break;
            case 'C': 
                    if (i != 0 &amp;&amp; array[i-1] == 'X')    //XC = 90
                    { 
                        result += 90;
                        i--;
                    } 
                    else
                    {
                        result += 100;
                    }
                    break;
 for (char currentDigit:  number.toCharArray())



identify the variable elements whithing this code duplication and make them actula variables, then extract the logic to a method the getst the variables as parameters. Uning an enum to represent individual roman digits helps a lot:

    public class RomanNumbers {
        enum DigitValue {
            DIGIT_INVALID('-', 0),
            DIGIT_I('I', 1),
            DIGIT_V('V', 5),
            DIGIT_X('X', 10),
            DIGIT_L('L', 50),
            DIGIT_C('C', 100),
            DIGIT_D('D', 500),
            DIGIT_M('M', 1000),;
            private final char digit;
            private final int value;

            DigitValue(char digit, int value) {
                this.digit = digit;
                this.value = value;
            }

            static DigitValue getFor(char digit) {
                DigitValue[] values = values();
                for (DigitValue digitValue : values) {
                    if (digitValue.digit == digit) {
                        return digitValue;
                    }
                }
                throw new IllegalArgumentException(digit
                        + " is not valid part of a roman number");
            }

        }

        // member variable neede because we cannot return more than one value
        private static int result;  // static because you refused to create an actual object.

        public static void main(String[] args) {
            System.out.println("Enter roman number from I to MMMCMXCIX (1 to 3999), q to quit: ");
            Scanner in = new Scanner(System.in);

            boolean done = false;
            while (!done
                    &amp;&amp; in.hasNext()) {
                String number = in.next();
                if (number.equals("q")) {
                    done = true;
                } else {
                    result = 0;
                    char[] array = number.toCharArray();

                    for (int i = number.length()
                            - 1; i &gt;= 0; i--) {
                        DigitValue currentDigit = DigitValue.getFor(array[i]);
                        DigitValue digitBefore = i &gt; 0 ? DigitValue.getFor(array[i- 1]) : DigitValue.INVALID);

                        switch (currentDigit) {
                            case DIGIT_I:
                                result += 1;
                                break;
                            case DIGIT_X:
                                i = caculateFor(currentDigit, digitBefore, DigitValue.DIGIT_I, i);
                                break;
                            case DIGIT_C:
                                i = caculateFor(currentDigit, digitBefore, DigitValue.DIGIT_X, i);
                                break;
                            case DIGIT_M:
                                i = caculateFor(currentDigit, digitBefore, DigitValue.DIGIT_C, i);
                                break;
                            case DIGIT_V:
                                i = caculateFor(currentDigit, digitBefore, DigitValue.DIGIT_I, i);
                                break;
                            case DIGIT_L:
                                i = caculateFor(currentDigit, digitBefore, DigitValue.DIGIT_X, i);
                                break;
                            case DIGIT_D:
                                i = caculateFor(currentDigit, digitBefore, DigitValue.DIGIT_C, i);
                                break;
                            default:
                                System.out.println("Not correct roman number");
                                break;
                        }
                    }
                    System.out.println("Corresponding decimal number is: "
                            + result);
                }
            }
            in.close();
        }

        private static int caculateFor(DigitValue currentDigitValue,
                DigitValue digitBefore,
                DigitValue reducingprevousDigit,
                int loopIndex) {
            result += currentDigitValue.value;
            if (digitBefore == reducingprevousDigit) {
                result -= reducingprevousDigit.value;
                loopIndex--;
            }
            return loopIndex;
        }
    }