这是罗马数字转为十进制数的后序
题目要求:将十进制数字转化为罗马数字,数值范围是[1,3999]
在罗马数字转化为十进制数的博客中,我简单的介绍了一下如何将罗马数字转化为十进制数字。在这道题目里,我们需要进一步了解十进制数转换为罗马数字的协议
- 罗马单个数字共有7个,即I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000)
- 可以被减去的值只有I(1)、X(10)、C(100),且每个值最多只可以减去一次
- 左减时不可以跨位数,例如99不能被表示为IC,而是XCIX
- 多个相同字母连续出现时表示相加,但是字母不能重复出现超过4次
综上所述,个位上的数可以由I、V、X表示出来,同理,十位上的树可以由X、L、C表示,百位上可以由C、D、M表示,千位上则为M(数字不超过3999)
所以可以分别对整数的每一位上的值进行计算,得出相应的罗马数字值,并最后合并为最终得罗马数字
思路一:遍历每一位的值转换为罗马数字
我尝试了两种数据存储方法,先尝试了map,感觉性能较差,然后尝试了array,性能的提升并不显著
//map
public String intToRoman(int num) {
Map<Integer, Character> romanIntMap = new HashMap<Integer, Character>();
romanIntMap.put(1, 'I');
romanIntMap.put(5, 'V');
romanIntMap.put(10, 'X');
romanIntMap.put(50, 'L');
romanIntMap.put(100, 'C');
romanIntMap.put(500, 'D');
romanIntMap.put(1000, 'M');
StringBuilder finalResult = new StringBuilder();
for(int i = 1 ; num>0 ; i*=10){
StringBuilder result = new StringBuilder("");
int digit = num%10;
if(digit==0){
}else if(digit<=3){
for(int j = 0 ; j<digit ; j++){
result.append(romanIntMap.get(i));
}
}else if(digit==4){
result.append(romanIntMap.get(i*5));
result.append(romanIntMap.get(i));
}else if(digit==5){
result.append(romanIntMap.get(i*5));
}else if(digit<=8){
for(int j = 0 ; j<digit-5 ; j++){
result.append(romanIntMap.get(i));
}
result.append(romanIntMap.get(i*5));
}else{
result.append(romanIntMap.get(i*10));
result.append(romanIntMap.get(i));
}
finalResult.insert(0,result.reverse());
num /= 10;
}
return finalResult.toString();
}
//数组
public String intToRoman2(int num){
char[] romans = new char[]{'I','V','X','L','C','D','M'};
StringBuilder finalResult = new StringBuilder();
for(int i = 0 ; num>0 ; i++){
StringBuilder result = new StringBuilder("");
int digit = num%10;
num /= 10;
if(digit==0){
continue;
}else if(digit<=3){
for(int j = 0 ; j<digit ; j++){
result.append(romans[i*2]);
}
}else if(digit==4){
result.append(romans[i*2+1]);
result.append(romans[i*2]);
}else if(digit==5){
result.append(romans[i*2+1]);
}else if(digit<=8){
for(int j = 0 ; j<digit-5 ; j++){
result.append(romans[i*2]);
}
result.append(romans[i*2+1]);
}else{
result.append(romans[i*2+2]);
result.append(romans[i*2]);
}
finalResult.insert(0,result.reverse());
}
return finalResult.toString();
}
思路二:穷尽枚举
因为题设中输入罗马数字是一定区间上的值,因此它的特殊情况是可以穷尽的
我们从个位入手来考虑每一位上较为特殊的情况
- ==9 : IX
- ==5 : V
- ==4 : IV
- <4 : I*n
也就是说,由大至小减去后剩下的值都有对应的罗马数字存在
public String intToRoman(int num) {
int[] values = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
String[] strs = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
StringBuilder sb = new StringBuilder();
for(int i=0;i<values.length;i++) {
while(num >= values[i]) {
num -= values[i];
sb.append(strs[i]);
}
}
return sb.toString();
}
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。