罗马数字和整数的互相转换
- 首先根据题目要求我们分析一下罗马数字和整数之间的相互转换规则:
- 基本的单位有
* I -- 1
* V -- 5
* X -- 10
* L -- 50
* C -- 100
* D -- 500
* M -- 1000 - 罗马数字采用的是5进制;逢5即变。
- 大的单位在左,小的单位在右,各级之间采用相加的关系,
- 一个字符或者俩个字符代表一个特定的整数
- 特殊的情况是表示4,9这类数字的时候采用双字符表示,即小的单位排在大的单位前表示大的单位减去小的单位,例如IV -- > 5-1 = 4 ,仅仅适用于以下六种情况 IV -- 4 ; IX 9; XL -- 40; XC -- 90; CD--400;CM--900;
- 这类算法模型类似于我们通常所说的‘摩尔斯电码’,具有一定的映射关系和替换规则,只要我们认真的分析,一定能够破解其中的秘密。
- 下面是我自己用Java代码编写的算法,如果代码中有不合适地方或者小伙伴们有更好的算法的话,能够及时指出或者联系我 qq: 476403337。
罗马数字转整数:
-
class Solution { public int romanToInt(String s) { int res = 0; ArrayList<String> rs = romanStrings(s); for(String st : rs){ res += singleRomanNum(st); } return res; } /* * 判断相邻俩个字符等级顺序 */ public boolean levelCompare(char a,char b){ if(a=='I'&&b=='V'||a=='I'&&b=='X'||a=='X'&&b=='L' ||a=='X'&&b=='C'||a=='C'&&b=='D'||a=='C'&&b=='M'){ return false; }else{ return true; } } /** * 将一个字符串分解为指定的罗马数字链表 * @param s * @return */ public ArrayList<String> romanStrings(String s){ char [] c = s.toCharArray(); int len = c.length; ArrayList<String> roman = new ArrayList<>(); if(len==1){ roman.add(s); }else{ for(int i=1;i<len;i++){ if(levelCompare(c[i-1], c[i])){ roman.add(String.valueOf(c[i-1])); }else{ roman.add(String.valueOf(c[i-1]+String.valueOf(c[i]))); i++; } } if(levelCompare(c[len-2], c[len-1])){ roman.add(String.valueOf(c[len-1])); } } return roman; } /* * 单个罗马字母转数字 */ public int singleRomanNum(String s){ int res = 0; switch (s) { case "I": res = 1; break; case "V": res = 5; break; case "X": res = 10; break; case "L": res = 50; break; case "C": res = 100; break; case "D": res = 500; break; case "M": res = 1000; break; case "IV": res = 4; break; case "IX": res = 9; break; case "XL": res = 40; break; case "XC": res = 90; break; case "CD": res = 400; break; case "CM": res = 900; break; default: break; } return res; } }
整数转罗马数字:
-
class Solution { public String intToRoman(int number){ String res = ""; ArrayList<Integer> nums = numberList(number); ArrayList<String> romans = new ArrayList<>(); for(int i=0;i<nums.size();i++){ romans.add(numSubToRoman(i, nums.get(i))); } for(int j=romans.size()-1;j>=0;j--){ res += romans.get(j); } return res; } /** * 获取一个整数的各位数字 -- 返回一个包含给定数字各位数字的数组 ,数组长度为数字位数,索引从0 开始依次为 个位,十位,百位。。。 * @param number * @return */ public ArrayList<Integer> numberList(int number){ ArrayList<Integer> res = new ArrayList<>(); int numSub = 0; do { numSub = number % 10; res.add(numSub); number /= 10; } while (number!=0); return res; } /** * 单个的位置上的数字转为罗马字符 * @param pos 给定数字所在的位 -- > 个位 , 十位 。。 * @param num 所在位的数值 0 --- > 9 * @return 对应的罗马数字。 */ public String numSubToRoman(int pos,int num){ String res = ""; switch (pos) { case 0: res = singlePosNumToRoman(num, "I", "V", "X"); break; case 1: res = singlePosNumToRoman(num, "X", "L", "C"); break; case 2: res = singlePosNumToRoman(num, "C", "D", "M"); break; case 3: res = singlePosNumToRoman(num, "M", "", ""); break; default: break; } return res; } /** * 单个位数的数字转换为罗马数字 * @param num 输入位数上的单个数字 * @param one 当前位数的1 * @param five 当前位数的5 * @param ten 当前位数的10 * @return 单个罗马数字 */ public String singlePosNumToRoman(int num,String one,String five,String ten){ String res = ""; if(num<4){ for(int i=0;i<num;i++){ res += one; } }else if(num == 4){ res += (one + five); }else if(num == 9){ res += (one + ten); }else{ res += five; for(int i=5;i<num;i++){ res += one; } } return res; } }