想法一:可以先建立一个表格,里面有特殊值对应的字符串,当输入一个数num时,找出不大于num的最大特殊值x,同时输出x代表的字符串。接着,num=num-x,重复上述操作,直到num=0。
这个表格可以用一个整形数组和一个字符串数组共同建立。需要注意的是这两个数组中的数值和字符串需要一一对应,而且数值从大到小排列可以更方便地遍历。代码如下。
class Solution {
public String intToRoman(int num) {
int[]arr={1000,900,500,400,100,90,50,40,10,9,5,4,1};
String[]s={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
StringBuilder sb=new StringBuilder();
for(int i=0;i<13;i++){
while(num>=arr[i]){
sb.append(s[i]);
num-=arr[i];
}
}
return sb.toString();
}
}
想法二:枚举法。由于最大的整数为3999,说明了num最多只有四位数。千位数为1-3,百位、十位、个位都为1-9,而将这些数字对应的字符串列举出来并不复杂。
class Solution {
public String intToRoman(int num) {
String[]s1={"","M","MM","MMM"};//有空字符是因为当某一位数为零的时候就可以取空
String[]s2={"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"};
String[]s3={"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"};
String[]s4={"","I","II","III","IV","V","VI","VII","VIII","IX"};
return s1[num/1000]+s2[(num%1000)/100]+s3[((num%1000)%100)/10]+s4[((num%1000)%100)%10];
}
}
想法三:将非400、900、40、90、4、9的字符按照从小到大的顺序存储,将整数的每一位存储在一个int数组中,按照千位数、百位数、十位数、个位数来排列。对于每一位数来说,都可以分五种情况:1、等于4;2、等于9;3、等于5;4、大于零但不是4、5、9;5、等于0。对于第4种情况,其对应字符串可以用for循环来求。在草稿纸上写出求出每一位数这五种情况下的字符串值的代码,发现了整型数组下标和字符型数组下标存在某种关系。在这里直接拷贝了Dicuss中的一份代码。
class Solution {
char [] dict = {'I','V','X','L','C','D','M'};
public String intToRoman(int num) {
int maxDigit = 4;
StringBuilder result = new StringBuilder();
int [] nums = new int[maxDigit];
for(int i=1;num!=0;i++){
int remainder = num % 10;
num = num / 10;
nums[i-1] = remainder;
}
for (int i=maxDigit-1;i>=0;i--){
int n = nums[i];
if (n==9||n==4){
result.append(dict[2*i]);
result.append(dict[(n==9)?(2*i+2):(2*i+1)]);
}else{
if (n>=5){
result.append(dict[2*i+1]);
n=n-5;
}
while (n!=0){
n--;
result.append(dict[2*i]);
}
}
}
return result.toString();
}
}
小结:对于这种有限个情况的问题,可以考虑用枚举法