罗马数简要说明
罗马数字符
I
: 1
V
:5
X
:10
L
:50
C
:100
D
:500
M
:1000
特殊字符集
IV
:4
IX
:9
XL
:40
XC
:100
CD
:400
CM
:900
一般规律
例如:III=3 VI=5+1=6 VII=5+2=7 XX=10+10=20 LX=5+10=60 MMM=1000+1000+10000=3000 MDLV=1000+500+50+5=1555
题目:输入一个int类型转罗马数,输入一个罗马数转int int∈[1,3999] 且为整数
int转罗马数
思路分析由于有有限的对应情况,因此可以保存所对应的关系去作为处理关键。分别找出千百十个位对应的数字,找到对应的数组的下标,即为对应关系
代码如下
public String intToRoman(int num) {
if (num > 3999 || num < 0) {
return "";
}
String result = "";
//千位数字 分别代表 千位没有值 1000 2000 3000
String[] kb = new String[]{"", "M", "MM", "MMM"};
//百位 分别代表 百位没有值 100 200 300 400 500 600 700 800 900
String[] hundreds = new String[]{"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
//十位
String[] decade = new String[]{"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
//个位
String[] unit = new String[]{"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
result = kb[num / 1000] + hundreds[num % 1000 / 100] + decade[num % 100 / 10] + unit[num % 10];
return result;
}
罗马数转int
思路分析。算法提取过程:罗马数总体规律是符合求和规律的,只有个别的特殊情况需要特别处理,这个几个数字分别是 特殊字符集。因此总体实现思路就是遍历字符串的每个字符,寻到与之对应的数字做相加操作,遇到这些特殊字符集,再单独处理。特殊字符集规律提取过程:依次遍历字符,非特殊字符集当前位的大小一定是<=
前一位的,只要不满足此规律就是特殊字符集
代码如下
public int romanToInt(String s) {
int length = s.length();
if (length == 0) {
return 0;
}
int[] roman = new int[256];
//以下为赋值操作
roman['I'] = 1;
roman['V'] = 5;
roman['X'] = 10;
roman['L'] = 50;
roman['C'] = 100;
roman['D'] = 500;
roman['M'] = 1000;
int result = roman[s.charAt(0)];
for (int i = 1; i < s.length(); i++) {
//都加上
int temp = roman[s.charAt(i)];
int last = roman[s.charAt(i - 1)];
result += temp;
//判断额外增加的比如4 执行到现在结果为6要减去2*1
if (last < temp) {
result -= last << 1;
}
}
return result;
}
另外补充下,另外一个知识点。就是
int[] roman=new int[256];
roman['I']=1;
分别是什么东西
计算机是不认识所有字符的,只识别0和1这两个数字,至于为啥,这个涉及的东西比较多就不过多说明了。所以就有一个表叫ASCII
表,这个表规定了一些操作字符的一一对应关系,具体对应关系百度百科都有。
所以这两行代码的含义就是 声明一个数组,长度为ASCII
表长度,即为256
对数组的某个下标进行赋值操作 'L'
如果我没有记错对应的十进制就是73
,所以这行代码的意思就是 数组下标73
赋值为1
当然对于这个问题来说就算不声明256
也是没有问题的 大写字符的取值范围为65~90
所以只声明一个长度为26
的数组,下标为'大写字符比如:I'-'A'
就可以了,这方面可以优化