12.Integer to Roman (第二周)

来源:互联网 发布:模拟退火算法的改进 编辑:程序博客网 时间:2024/06/03 21:07

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)
链接里面的题目我在上一周的博客里面已经提到了()

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

罗马数字 阿拉伯数字 I 1 V 5 X 10 L 50 C 100 D 500 M 1000

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

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

拿个位上的数字举例子:

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

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

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

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