分享两个算法,罗马数与整数互相转化(Java)

罗马数简要说明

罗马数字符

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'就可以了,这方面可以优化

点赞