简体   繁体   中英

Roman Numeral to Integer

i am trying to find the simplest algorithm to covert a Roman Numeral to int.I have this code from Rosetta code but there are few things in the code that doesnt make sense.

In the for loop in the code below how is the roman numeral being iterated through? Can any explain how the nested for loop here work or do you have a simpler way of writing this algorithm

public class Roman {

    enum Numeral {
        I(1), IV(4), V(5), IX(9), X(10), XL(40), L(50), XC(90), C(100), CD(400), D(500), CM(900), M(1000);
        int weight;

        Numeral(int weight) {
            this.weight = weight;
        }
    };

    public static String roman(long n) {

        if( n <= 0) {
            throw new IllegalArgumentException();
        }

        StringBuilder buf = new StringBuilder();

        final Numeral[] values = Numeral.values();
        for (int i = values.length - 1; i >= 0; i--) {
            while (n >= values[i].weight) {
                buf.append(values[i]);
                n -= values[i].weight;
            }
        }
        return buf.toString();
    }

    public static void test(long n) {
        System.out.println(n + " = " + roman(n));
    }

    public static void main(String[] args) {
        test(1999);
        test(25);
        test(944);
        test(0);
    }

The roman literals are being iterated from highest to lowest. This makes perfect sense. This is how one should do it because you want to extract the biggest item first. Once you're done with it, you want to extract the second biggest item and so on. While extracting an item it may fit 0,1,2,3,... times into the number you currently have left. That's the meaning/purpose of this loop there.

        while (n >= values[i].weight) {
            buf.append(values[i]);
            n -= values[i].weight;
        }

And I think that's pretty much the simplest way to write this algorithm. You just need to grasp the idea.

public int romanToInt(String s) {
        int total = 0, currentVal = 0, prevVal = 0;

        for(int i=s.length()-1; i>=0; i--) {
            switch(s.charAt(i)) {
                case 'I' : currentVal = 1; break;
                case 'V' : currentVal = 5; break;
                case 'X' : currentVal = 10; break;
                case 'L' : currentVal = 50; break; 
                case 'C' : currentVal = 100; break;
                case 'D' : currentVal = 500; break;
                case 'M' : currentVal = 1000; break; 
                default: break;
            }
            total += (currentVal < prevVal) ? -1 * currentVal : currentVal;
            prevVal = currentVal;
        }

        return total;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM