1. 程式人生 > >羅馬數字與阿拉伯數字互轉

羅馬數字與阿拉伯數字互轉

描述: Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
(給定一個羅馬數字,將其轉換為整數。輸入保證在1到3999的範圍內。)

描述:Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.(給定一個整數,將其轉換為羅馬數字。
輸入保證在1到3999的範圍內。)

羅馬數字介紹

羅馬數字是歐洲在阿拉伯數字(實際上是印度數字)傳入之前使用的一種數碼,現在應用較少。它的產生晚於中國甲骨文中的數碼,更晚於埃及人的十進位數字。但是,它的產生標誌著一種古代文明的進步。

記數方法

基本數字 對應的阿拉伯數字為
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
  1. 相同的數字連寫、所表示的數等於這些數字相加得到的數、如:Ⅲ=3;
  2. 小的數字在大的數字的右邊、所表示的數等於這些數字相加得到的數、 如:Ⅷ=8、Ⅻ=12;
  3. 小的數字(限於 I、X 和 C)在大的數字的左邊、所表示的數等於大數減小數得到的數、如:Ⅳ=4、Ⅸ=9;
  4. 正常使用時、連寫的數字重複不得超過三次;
  5. 在一個數的上面畫一條橫線、表示這個數擴大 1000 倍。

組數規則

有兩條須注意掌握:

  1. 基本數字 Ⅰ、X 、C 中的任何一個、自身連用構成數目、或者放在大數的右邊連用構成數目、都不能超過三個;放在大數的左邊只能用一個;
  2. 不能把基本數字 V 、L 、D 中的任何一個作為小數放在大數的左邊採用相減的方法構成數目;放在大數的右邊採用相加的方式構成數目、只能使用一個;

對照舉例

  • 個位數舉例

    Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9

  • 十位數舉例

    Ⅹ-10、Ⅺ-11、Ⅻ-12、XIII-13、XIV-14、XV-15、XVI-16、XVII-17、XVIII-18、XIX-19、XX-20、XXI-21、XXII-22、XXIX-29、XXX-30、XXXIV-34、XXXV-35、XXXIX-39、XL-40、L-50、LI-51、LV-55、LX-60、LXV-65、LXXX-80、XC-90、XCIII-93、XCV-95、XCVIII-98、XCIX-99

  • 百位數舉例

    C-100、CC-200、CCC-300、CD-400、D-500、DC-600、DCC-700、DCCC-800、CM-900、CMXCIX-999

  • 千位數舉例

    M-1000、MC-1100、MCD-1400、MD-1500、MDC-1600、MDCLXVI-1666、MDCCCLXXXVIII-1888、MDCCCXCIX-1899、MCM-1900、MCMLXXVI-1976、MCMLXXXIV-1984、MCMXC-1990、MM-2000、MMMCMXCIX-3999

演算法分析

  • 羅馬數字轉阿拉伯數字

    class Solution {
        public int roman2Integer(String roman) {
            if (roman.length() < 1) {
                return 0;
            }
            // 定義一個map將對映關係儲存起來
            Map<Character, Integer> map = new HashMap<>();
            map.put('I', 1);
            map.put('V', 5);
            map.put('X', 10);
            map.put('L', 50);
            map.put('C', 100);
            map.put('D', 500);
            map.put('M', 1000);
    
            int result = 0;
            char[] chars = roman.toCharArray();
            for (int i = 0; i < chars.length; i++) {
                if (i < chars.length - 1) {
                    // 兩兩比較根據規則左小右大則為減,左大右小則為加
                    if (map.get(chars[i]) < map.get(chars[i + 1])) {
                        result -= map.get(chars[i]);
                    } else {
                        result += map.get(chars[i]);
                    }
                } else {
                    // 最後一位必為加
                    result += map.get(chars[i]);
                }
            }
            return result;
        }
    }
    

    這個是自己琢磨的,感覺不夠好,有好的演算法還希望大家多多交流~~

  • 下面貼個LeetCode上的

    public int romanToInt(String s) {
        int sum=0;
        if(s.indexOf("IV")!=-1){sum-=2;}
        if(s.indexOf("IX")!=-1){sum-=2;}
        if(s.indexOf("XL")!=-1){sum-=20;}
        if(s.indexOf("XC")!=-1){sum-=20;}
        if(s.indexOf("CD")!=-1){sum-=200;}
        if(s.indexOf("CM")!=-1){sum-=200;}
    
        char c[]=s.toCharArray();
        int count=0;
    
       for(;count<=s.length()-1;count++){
           if(c[count]=='M') sum+=1000;
           if(c[count]=='D') sum+=500;
           if(c[count]=='C') sum+=100;
           if(c[count]=='L') sum+=50;
           if(c[count]=='X') sum+=10;
           if(c[count]=='V') sum+=5;
           if(c[count]=='I') sum+=1;
    
       }
       return sum;
    }
    
  • 阿拉伯數字轉羅馬數字(參見羅馬數字C++實現)

    class Solution {
        public String int2Roman(int num) {
            // 個、十、百、千位對映到羅馬數字的對映表
            String[][] mapping = {
                    {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"},
                    {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"},
                    {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"},
                    {"", "M", "MM", "MMM"}
            };
    
            return mapping[3][num / 1000 % 10]  // 千位
                    + mapping[2][num / 100 % 10]// 百位
                    + mapping[1][num / 10 % 10] // 十位
                    + mapping[0][num % 10];     // 個位
        }
    }