问题:
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];
}
}
来源:oschina
链接:https://my.oschina.net/u/2968041/blog/1523710