整数转罗马数字

罗马数字包含以下七种字符: I, V, X, LCD 和 M

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 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。

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

示例 1:

输入: 3
输出: "III"

示例 2:

输入: 4
输出: "IV"

示例 3:

输入: 9
输出: "IX"

示例 4:

输入: 58
输出: "LVIII"
解释: L = 50, V = 5, III = 3.

示例 5:

输入: 1994
输出: "MCMXCIV"
解释: M = 1000, CM = 900, XC = 90, IV = 4.

方法一:

(1)看到这个题,我首先想到的就是取得传入 的各个数字,由于题目已经限定了传入的数字在1-3999之间,所以我用了一个int型的nums数组来存放获取到的各个位,数组的下标分别是0-3,一次表示个位,十位, 百位,千位上的数字,如果没有的话就是0;

(2)其次我将题目中描述的字符与数值的对应关系放到直接放到了一个char  *的数组中,便于之后使用;

(3)接着,就是从高位开始遍历nums数组,按照规则,将各个位对应的字符追加到需要输出的字符串中。

实现代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char * intToRoman(int num){
    int nums[4];
    memset(nums, 0sizeof(nums));

    if(num<1 || num >3999){
        return NULL;
    }
    char *map[]={"I"//1
              "V"//5
              "X"//10
              "L"//50
              "C"//100
              "D"//500
              "M"}; //1000
    
    int tmp=num;
    int ii=0;
    while(tmp!=0){
        int get_num=tmp%10;
        nums[ii]=get_num;
        ii++;
        tmp=tmp/10;
    }

    static char  ret_string[1024];
    memset(ret_string, 0sizeof(ret_string));
    ii=3;
    for(;ii>=0;ii--){
        if(nums[ii]!=0 && ii ==3){
            int tmp=1;
            while(tmp<=nums[ii]){
                strcat(ret_string, map[6]);
                tmp++;
            }
        }else if(nums[ii]!=0 && ii ==2){
            int tmp=1;
            if(nums[ii]<=3){
                while(tmp<=nums[ii]){
                    strcat(ret_string, map[4]);
                    tmp++;
                }
            }else if(nums[ii] == 4){
                strcat(ret_string, map[4]);
                strcat(ret_string, map[5]);
            }else if(nums[ii] ==5){
                strcat(ret_string, map[5]);
            }else if(nums[ii] >=6 && nums[ii]<=8){
                tmp=6;
                strcat(ret_string, map[5]);
                while(tmp<=nums[ii]){
                    strcat(ret_string, map[4]); 
                    tmp++;
                }
            }else{
                strcat(ret_string, map[4]);
                strcat(ret_string, map[6]);
            }

        }else if(nums[ii]!=0 && ii ==1){
            int tmp=1;
            if(nums[ii]<=3){
                while(tmp<=nums[ii]){
                    strcat(ret_string, map[2]);
                    tmp++;
                }
            }else if(nums[ii] == 4){
                strcat(ret_string, map[2]);
                strcat(ret_string, map[3]);
            }else if(nums[ii] ==5){
                strcat(ret_string, map[3]);
            }else if(nums[ii] >=6 && nums[ii]<=8){
                tmp=6;
                strcat(ret_string, map[3]);
                while(tmp<=nums[ii]){
                    strcat(ret_string, map[2]); 
                    tmp++;
                }
            }else{
                strcat(ret_string, map[2]);
                strcat(ret_string, map[4]);
            }

        }else if(nums[ii]!=0 && ii ==0){
            int tmp=1;
            if(nums[ii]<=3){
                while(tmp<=nums[ii]){
                    strcat(ret_string, map[0]);
                    tmp++;
                }
            }else if(nums[ii] == 4){
                strcat(ret_string, map[0]);
                strcat(ret_string, map[1]);
            }else if(nums[ii] ==5){
                strcat(ret_string, map[1]);
            }else if(nums[ii] >=6 && nums[ii]<=8){
                tmp=6;
                strcat(ret_string, map[1]);
                while(tmp<=nums[ii]){
                    strcat(ret_string, map[0]); 
                    tmp++;
                }
    
            }else{
                strcat(ret_string, map[0]);
                strcat(ret_string, map[2]);
            }
        }

    }

    return ret_string;
}
方法二:
通过枚举出所有的可能性,建立个位,十位,百位,千位的数字与字符的对应关系即可
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char * intToRoman(int num){
    int nums[4];
    memset(nums, 0sizeof(nums));
    static char ret_string[1024];
    memset(ret_string, 0sizeof(ret_string));

    if(num<1 || num >3999){
        return NULL;
    }
    char* map[4][10] = {
            {"","I","II","III","IV","V","VI","VII","VIII","IX"},
            {"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"},
            {"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"},
            {"","M","MM","MMM"}};

    int tmp=num;
    int ii=0;
    while(tmp!=0){
        int get_num=tmp%10;
        nums[ii++]=get_num;
        tmp=tmp/10;
    }
    ii=3;
    for(;ii>=0;ii--){
        if(nums[ii]!=0 ){
            strcat(ret_string, map[ii][nums[ii]]);
        }
    }

    return ret_string;
}
 方法三:
贪心法则:我们每次尽量使用最大的数来表示。 比如对于 1994 这个数,如果我们每次尽量用最大的数来表示,依次选 1000,900,90,4,会得到正确结果 MCMXCIV。

所以,我们将哈希表按照从大到小的顺序排列,然后遍历哈希表,直到表示完整个输入。

代码如下:

  class Solution {
public:
    string intToRoman(int num) {
        int values[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        string reps[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};

        string res;
        int
        for (int i = 0; i < 13; i ++ )  //这里不使用图里的count了,一遍一遍来就行了
            while(num >= values[i])
            {
                num -= values[i];
                res += reps[i];
            }
        return res;
    }
};

此代码为C++的代码。




作者:z1m
链接:https://leetcode-cn.com/problems/integer-to-roman/solution/tan-xin-ha-xi-biao-tu-jie-by-ml-zimingmeng/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/integer-to-roman
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

原文地址:https://www.cnblogs.com/pigdragon/p/12420007.html