【中等】12-整数转罗马数字 Integer to Roman

题目

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.

例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

I can be placed before V (5) and X (10) to make 4 and 9. 
X can be placed before L (50) and C (100) to make 40 and 90. 
C can be placed before D (500) and M (1000) to make 400 and 900.

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999.

给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。

Example1

Input: 3
Output: "III"

Example2

Input: 4
Output: "IV"

Example3

Input: 9
Output: "IX"

Example4

Input: 58
Output: "LVIII"
Explanation: L = 50, V = 5, III = 3.

Example5

Input: 1994
Output: "MCMXCIV"
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/integer-to-roman

解法

方法一:贪心算法

解题思路

第一反应肯定是从大到小开始计算数字中可以放多少个对应的符号,如2279可以放2个1000,0个500,2个100,1个50,2个10,1个5,4个1,但是由于4/40/400和9/90/900出现时会不同,所以我们吧这6个数字也定义进符号中即可。

代码

class Solution {
public:
    string intToRoman(int num) {
        string res = "";
        int div[13] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        string symble[13] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
        int start = 0;
        while(num > 0){
            if(num < div[start]) start++;
            else{
                res += symble[start];
                num -= div[start];
            }
        }
        return res;
    }
};

方法二:逐位计算

解题思路

每一位都有0-9这10种赋值(第一位没有0),分别由对应的1和5构成,如个位数由I V构成,十位数由X L构成,其中,是4和9时字符比较特殊,所以,我们只要逐位计算出每个数位对应的字符再连接即可。

如果这位数为9,那么就是对应为9的情况(如CM XC IX),如果是4,就是CD XL IV,如果是其他数字就用1和5具体排列。从最后一位开始向前,判断该位可以转化的对应的字符,将每一位的字符连接在一起。

代码

class Solution {
public:
    string intToRoman(int num) {
        string res = "";
        int div[7] = {1,5,10,50,100,500,1000};
        string symbol[7] = {"I", "V", "X", "L", "C", "D", "M"};
        int l = 2;
        while(num>0){
            int curr = num%10;
            num /= 10;
            string add = "";
            if(curr == 4) add = symbol[l-2]+symbol[l-1];
            else if(curr == 9) add = symbol[l-2]+symbol[l];
            else{
                if(curr >= 5){
                    add = symbol[l-1];
                    curr -= 5;
                }
                for(int i = 0; i < curr; ++i){
                    add += symbol[l-2];
                }
            }
            res = add + res;
            l += 2;
        }
        return res;
    }
};
posted @ 2020-04-21 18:24  陌良  阅读(126)  评论(0编辑  收藏  举报