整数转换为罗马数字 Integer to Roman

断了今生、忘了曾经 提交于 2020-03-01 10:36:28

问题:

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.

解决:

【注】

基本字符

I

V

X

L

C

D

M

相应的阿拉伯数字表示为

1

5

10

50

100

500

1000

例如整数 1437 的罗马数字为 MCDXXXVII, 我们不难发现,千位,百位,十位和个位上的数分别用罗马数字表示了。 1000 - M, 400 - CD, 30 - XXX, 7 - VII。所以我们要做的就是用取商法分别提取各个位上的数字,然后分别表示出来:
【罗马数字】
1~9: {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
10~90: {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
100~900: {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
1000~3000: {"M", "MM", "MMM"}.

设数字与罗马数字之间的对应关系:roman[] = {'M', 'D', 'C', 'L', 'X', 'V', 'I'};
以100~900为例,我们可以分为四类:100到300一类res += roman[n],400一类res += roman[n]+roman[n-1],500到800一类res += roman[n - 1] + roman[n],900最后一类res+=roman[n] + roman[n-2]。每一位上的情况都是类似的,代码如下:

① 使用代码实现转换。

class Solution { //91ms
    public static String intToRoman(int num) {
        String res = "";
        char[] roman = {'M','D','C','L','X','V','I'};
        int[] value = {1000,500,100,50,10,5,1};
        for (int i = 0;i < 7;i += 2){//遍历roman数组
            int val = num / value[i];
            if (val < 4){
                for (int j = 1;j <= val;j ++){
                    res = res + roman[i];
                }
            }else if(val == 4){
                res = res + roman[i] + roman[i - 1];
            }else if (val > 4 && val < 9){
                res = res + roman[i - 1];
                for (int j = 6;j <= val;j ++){
                    res += roman[i];
                }
            }else if (val == 9){
                res = res + roman[i] + roman[i - 2];//若使用res += res + roman[i] + roman[i - 2]结果为161,变为了整数相加
            }
            num %= value[i];
        }
        return res;
    }
}

② 本题由于限制了输入数字范围这一特殊性,故而还有一种利用贪心算法的解法,建立一个数表,每次通过查表找出当前最大的数,减去再继续查表。

public class Solution { //93ms
    private static final String[] ROMAN = new String[]{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
    private static final int[] INTEGERS = new int[]{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
    public String intToRoman(int num) {
        StringBuilder sb = new StringBuilder();
        int index = 0;
        while (num > 0) {
            while (num >= INTEGERS[index]) {
                sb.append(ROMAN[index]);
                num -= INTEGERS[index];
            }
            index ++;
        }
        return sb.toString();
    }
}

③一种讨巧的做法,将所有的可能都列出来。

public class Solution {//95ms
    public String intToRoman(int num) {
        String M[] = {"", "M", "MM", "MMM"};
        String C[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
        String X[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
        String I[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
        return M[num / 1000] + C[(num % 1000) / 100] + X[(num % 100) / 10] + I[num % 10];
    }
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!