12.Integer to Roman (第二周)

Description

Integer to Roman - LeetCode

Given an integer, convert it to a roman numeral.

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

Input: 1
Output: "I"

Solution

跟另外一道题类似(Roman to Integer - LeetCode
链接里面的题目我在上一周的博客里面已经提到了()

首先我们要知道罗马数字每个数字对应的阿拉伯数字大小,如下表所示

罗马数字阿拉伯数字
I1
V5
X10
L50
C100
D500
M1000

首先想到的方法把每一个位数上面的数字取出来,然后按照千、百、十、个的顺序分解出每一个位数上面的数字。

然后按照不同的对应关系来完成对照。

拿个位上的数字举例子:

阿拉伯数字(num)罗马数字
1~3num * I (num个“I”组成的字符串)
4IV
5~8V + num * I
9IX

其他的位置同理,改变的只是对应的字母而已,所以一开始我写出了以下的代码:

Source Code

submission I

class Solution {
public:
    string intToRoman(int num) {
        int thousand = num / 1000;
        num = num % 1000;
        int hundred = num / 100;
        num = num % 100;
        int tens = num / 10;
        int ones = num % 10;

        return getThousandRoman(thousand) +
               getHundredRoman(hundred) + 
               getTensRoman(tens) +
               getOnesRoman(ones);
    }

    string getThousandRoman(int num) // 千位数对应的数字
    {
        if (num == 0)
        {
            return "";
        }
        else if (num == 3)
        {
            return "MMM";
        }
        else if (num == 2)
        {
            return "MM";
        }
        else if (num == 1)
        {
            return "M";
        }
        else 
        {
            return "";
        }
    }

    string getHundredRoman(int num) // 百位数对应的数字
    {
        if (num == 0)
        {
            return "";
        }
        if (num == 9)
        {
            return "CM";
        }
        else if (num >= 5)
        {
            return "D" + getDuplicateRoman(num - 5, "C");
        }
        else if (num == 4)
        {
            return "CD";
        }
        else 
        {
            return getDuplicateRoman(num, "C");          
        }
    }

    string getTensRoman(int num) // 十位数对应的数字
    {
        if (num == 0)
        {
            return "";
        }
        if (num == 9)
        {
            return "XC";
        }
        else if (num >= 5)
        {
            return "L" + getDuplicateRoman(num - 5, "X");
        }
        else if (num == 4)
        {
            return "XL";
        }
        else 
        {
            return getDuplicateRoman(num, "X");
        }
    }

    string getOnesRoman(int num) // 个位数对应的数字
    {
        if (num == 0)
        {
            return "";
        }
        if (num == 9)
        {
            return "IX";
        }
        else if (num >= 5)
        {
            return "V" + getDuplicateRoman(num - 5, "I");
        }
        else if (num == 4)
        {
            return "IV";
        }
        else 
        {
            return getDuplicateRoman(num, "I");
        }
    }

    string getDuplicateRoman(int num, string s) // 获取重复的字符
    {
        string ret = "";
        for (int i = 0 ; i < num ; i++)
        {
            ret += s;
        }
        return ret;
    }

};

Thinking

在完成上述代码之后我发现了代码长度偏长,我的函数中有很多重复的部分,唯一不同的是对应的字母,如果把这些字母也变成参数放进函数里面,就有了以下比较简短的代码:

submission II

class Solution {
public:
    string intToRoman(int num) {
        int thousand = num / 1000;
        num = num % 1000;
        int hundred = num / 100;
        num = num % 100;
        int tens = num / 10;
        int ones = num % 10;
        return getAnyRoman(thousand, "", "", "M") // 千位
            + getAnyRoman(hundred, "M", "D", "C") // 百位
            + getAnyRoman(tens, "C", "L", "X") // 十位
            + getAnyRoman(ones, "X", "V", "I"); // 百位
    }

    /***
     * num  - 0~9
     * ten  - 十倍表示的字母(如个位对应"X")
     * five - 五倍表示的字母(如个位对应"V")
     * ten  - 一倍表示的字母(如个位对应"I")
     */
    string getAnyRoman(int num, string ten, string five, string one)
    {
        if (num == 0)
        {
            return "";
        }
        if (num == 9)
        {
            return one + ten;
        }
        else if (num >= 5)
        {
            return five + getDuplicateRoman(num - 5, one);
        }
        else if (num == 4)
        {
            return one + five;
        }
        else 
        {
            return getDuplicateRoman(num, one);
        }
    }

    string getDuplicateRoman(int num, string s) // 获取重复的字符
    {
        string ret = "";
        for (int i = 0 ; i < num ; i++)
        {
            ret += s;
        }
        return ret;
    }

};

Better Solution

参考别人的代码(Integer to Roman- LeetCode):

public static 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];
}

这位大神写的代码十分简短,但是思路是和我的一样的,不过这样子简短而又清晰的代码的确令人佩服!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值