将罗马数字转换为十进制

Dan*_*ook 39 java

我设法让我的代码将大多数罗马数字转换为适当的十进制值.但它不适用于某些特殊情况.示例:XCIX= 99但我的代码打印出来109.

这是我的代码.

public static int romanConvert(String roman)
{
    int decimal = 0;

    String romanNumeral = roman.toUpperCase();
    for(int x = 0;x<romanNumeral.length();x++)
    {
        char convertToDecimal = roman.charAt(x);

        switch (convertToDecimal)
        {
        case 'M':
            decimal += 1000;
            break;

        case 'D':
            decimal += 500;
            break;

        case 'C':
            decimal += 100;
            break;

        case 'L':
            decimal += 50;
            break;

        case 'X':
            decimal += 10;
            break;

        case 'V':
            decimal += 5;
            break;

        case 'I':
            decimal += 1;
            break;
        }
    }
    if (romanNumeral.contains("IV"))
    {
        decimal-=2;
    }
    if (romanNumeral.contains("IX"))
    {
        decimal-=2;
    }
    if (romanNumeral.contains("XL"))
    {
        decimal-=10;
    }
    if (romanNumeral.contains("XC"))
    {
        decimal-=10;
    }
    if (romanNumeral.contains("CD"))
    {
        decimal-=100;
    }
    if (romanNumeral.contains("CM"))
    {
        decimal-=100;
    }
    return decimal;
}
Run Code Online (Sandbox Code Playgroud)

Rav*_*lli 57

如果你反过来走路会很好.

public class RomanToDecimal {
    public static void romanToDecimal(java.lang.String romanNumber) {
        int decimal = 0;
        int lastNumber = 0;
        String romanNumeral = romanNumber.toUpperCase();
        /* operation to be performed on upper cases even if user 
           enters roman values in lower case chars */
        for (int x = romanNumeral.length() - 1; x >= 0 ; x--) {
            char convertToDecimal = romanNumeral.charAt(x);

            switch (convertToDecimal) {
                case 'M':
                    decimal = processDecimal(1000, lastNumber, decimal);
                    lastNumber = 1000;
                    break;

                case 'D':
                    decimal = processDecimal(500, lastNumber, decimal);
                    lastNumber = 500;
                    break;

                case 'C':
                    decimal = processDecimal(100, lastNumber, decimal);
                    lastNumber = 100;
                    break;

                case 'L':
                    decimal = processDecimal(50, lastNumber, decimal);
                    lastNumber = 50;
                    break;

                case 'X':
                    decimal = processDecimal(10, lastNumber, decimal);
                    lastNumber = 10;
                    break;

                case 'V':
                    decimal = processDecimal(5, lastNumber, decimal);
                    lastNumber = 5;
                    break;

                case 'I':
                    decimal = processDecimal(1, lastNumber, decimal);
                    lastNumber = 1;
                    break;
            }
        }
        System.out.println(decimal);
    }

    public static int processDecimal(int decimal, int lastNumber, int lastDecimal) {
        if (lastNumber > decimal) {
            return lastDecimal - decimal;
        } else {
            return lastDecimal + decimal;
        }
    }

    public static void main(java.lang.String args[]) {
        romanToDecimal("XIV");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @DanielFarmer - 注意它实际上并不是魔术,如果是家庭作业,你应该知道它为什么会起作用 (21认同)
  • IIX可以使用此代码.这是一个无效的数字. (8认同)
  • 如果我将IIXX作为输入,我得到20作为输出,这是错误的.不应该抛出错误. (2认同)

小智 39

试试这个 - 它简单而紧凑,工作非常顺利:

    public static int ToArabic(string number) {
        if (number == string.Empty) return 0;
        if (number.StartsWith("M")) return 1000 + ToArabic(number.Remove(0, 1));
        if (number.StartsWith("CM")) return 900 + ToArabic(number.Remove(0, 2));
        if (number.StartsWith("D")) return 500 + ToArabic(number.Remove(0, 1));
        if (number.StartsWith("CD")) return 400 + ToArabic(number.Remove(0, 2));
        if (number.StartsWith("C")) return 100 + ToArabic(number.Remove(0, 1));
        if (number.StartsWith("XC")) return 90 + ToArabic(number.Remove(0, 2));
        if (number.StartsWith("L")) return 50 + ToArabic(number.Remove(0, 1));
        if (number.StartsWith("XL")) return 40 + ToArabic(number.Remove(0, 2));
        if (number.StartsWith("X")) return 10 + ToArabic(number.Remove(0, 1));
        if (number.StartsWith("IX")) return 9 + ToArabic(number.Remove(0, 2));
        if (number.StartsWith("V")) return 5 + ToArabic(number.Remove(0, 1));
        if (number.StartsWith("IV")) return 4 + ToArabic(number.Remove(0, 2));
        if (number.StartsWith("I")) return 1 + ToArabic(number.Remove(0, 1));
        throw new ArgumentOutOfRangeException("something bad happened");
    }
Run Code Online (Sandbox Code Playgroud)

  • 好的解决方案 虽然有一个小问题:一封信不能连续重复超过3次,只能重复10次.你的算法将IIII转换为4; 但我假设您认为验证将留给用户! (6认同)
  • 验证步骤会很好,否则您会为“IVX”打印 14,这是无效输入。 (2认同)
  • 这是一个java代码,这听起来像C#给我! (2认同)

小智 25

假设哈希看起来像这样

Hashtable<Character, Integer> ht = new Hashtable<Character, Integer>();
    ht.put('i',1);
    ht.put('x',10);
    ht.put('c',100);
    ht.put('m',1000);
    ht.put('v',5);
    ht.put('l',50);
    ht.put('d',500);
Run Code Online (Sandbox Code Playgroud)

然后逻辑变得非常简单,从右到左依次为数字

public static int rtoi(String num)
{       
    int intNum=0;
    int prev = 0;
    for(int i = num.length()-1; i>=0 ; i--)
    {
            int temp = ht.get(num.charAt(i));
            if(temp < prev)
                intNum-=temp;
            else
                intNum+=temp;
            prev = temp;
    }
    return intNum;
}   
Run Code Online (Sandbox Code Playgroud)

  • 例如,这不适用于IIX (2认同)

Edw*_*rld 5

代码更少,效率更高。不太清楚,抱歉!

public int evaluateRomanNumerals(String roman) {
    return (int) evaluateNextRomanNumeral(roman, roman.length() - 1, 0);
}

private double evaluateNextRomanNumeral(String roman, int pos, double rightNumeral) {
    if (pos < 0) return 0;
    char ch = roman.charAt(pos);
    double value = Math.floor(Math.pow(10, "IXCM".indexOf(ch))) + 5 * Math.floor(Math.pow(10, "VLD".indexOf(ch)));
    return value * Math.signum(value + 0.5 - rightNumeral) + evaluateNextRomanNumeral(roman, pos - 1, value);
}
Run Code Online (Sandbox Code Playgroud)