LeetCode:Roman to Integer - 羅馬數字到阿拉伯數字的轉換

一、題目名稱java

Roman to Integer (羅馬數字到阿拉伯數字的轉換)數組

二、題目地址.net

https://leetcode.com/problems/roman-to-integer/code

三、題目內容blog

英文:Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.leetcode

中文:給出一個羅馬數字,將它轉換成整數。輸入在1-3999之間。開發

四、題目分析get

這個題目和題目#12(阿拉伯數字到羅馬數字的轉換)須要實現的功能相反,是將羅馬數字轉換爲阿拉伯數字。關於羅馬數字與十進制數字的規律,在 #12的解題方案 中已有說明,雖然羅馬數字並非明顯的十進制數字,但每一位都有共同的規律可循。string

五、解題方法1hash

根據羅馬數字每一個十進制位的共同規律,在解析羅馬數字的時候,能夠從高位到低位,逐位轉換成阿拉伯數字。

例如,表明單位1的羅馬數字爲「I」,單位5爲「V」,單位10爲「X」,那1-10的羅馬數字就是I、II、III、IV、V、VI、VII、VIII、IX、X。十位的狀況就是把「I」換成「X」、把「V」換成「L」、把「X」換成「C」,從而得出10-100的羅馬數字是X、XX、XXX、XL、L、LX、LXX、LXXX、XC、C。其他各位以此類推。

一個比較笨拙的Java實現代碼以下:

/**
 * 功能說明:LeetCode 13 - Roman to Integer 
 * 開發人員:Tsybius
 * 開發時間:2015年8月3日
 */
public class Solution {

    /**
     * 羅馬數字轉換爲阿拉伯數字
     * @param s 被轉換的羅馬數字
     * @return 轉換後的阿拉伯數字
     */
    public int romanToInt(String s) {

        String[] temp;
        String result = "";

        //千位
        temp = getArabicNumber(s, "M", " ", " ");
        result += temp[0];
        s = temp[1];
        
        //百位
        temp = getArabicNumber(s, "C", "D", "M");
        result += temp[0];
        s = temp[1];
        
        //十位
        temp = getArabicNumber(s, "X", "L", "C");
        result += temp[0];
        s = temp[1];

        //個位
        temp = getArabicNumber(s, "I", "V", "X");
        result += temp[0];
        s = temp[1];
        
        return Integer.parseInt(result);
    }
    
    /**
     * 將羅馬數字的首位轉換爲阿拉伯數字(須要指定具體位的一、五、10三個字母)
     * @param romanNumber 羅馬數字
     * @param one 一
     * @param five 五
     * @param ten 十
     * @return 數組
     *     第一項爲輸入羅馬數字中最高位數對應的阿拉伯數字
     *     第二項爲刪去該數字後剩餘部分的羅馬數字 
     */
    private String[] getArabicNumber(String romanNumber, 
        String one, String five, String ten) {

        //9
        if (romanNumber.length() >= 2 && 
            romanNumber.substring(0, 2).equals(one + ten)) {
            return new String[] { "9", romanNumber.substring(2) };
        }
        
        //8
        if (romanNumber.length() >= 4 && 
            romanNumber.substring(0, 4).equals(five + one + one + one)) {
            return new String[] { "8", romanNumber.substring(4) };
        }
        
        //7
        if (romanNumber.length() >= 3 && 
            romanNumber.substring(0, 3).equals(five + one + one)) {
            return new String[] { "7", romanNumber.substring(3) };
        }
        
        //6
        if (romanNumber.length() >= 2 && 
            romanNumber.substring(0, 2).equals(five + one)) {
            return new String[] { "6", romanNumber.substring(2) };
        }
        
        //5
        if (romanNumber.length() >= 1 && 
            romanNumber.substring(0, 1).equals(five)) {
            return new String[] { "5", romanNumber.substring(1) };
        }
        
        //4
        if (romanNumber.length() >= 2 && 
            romanNumber.substring(0, 2).equals(one + five)) {
            return new String[] { "4", romanNumber.substring(2) };
        }

        //3
        if (romanNumber.length() >= 3 && 
            romanNumber.substring(0, 3).equals(one + one + one)) {
            return new String[] { "3", romanNumber.substring(3) };
        }

        //2
        if (romanNumber.length() >= 2 && 
            romanNumber.substring(0, 2).equals(one + one)) {
            return new String[] { "2", romanNumber.substring(2) };
        }

        //1
        if (romanNumber.length() >= 1 && 
            romanNumber.substring(0, 1).equals(one)) {
            return new String[] { "1", romanNumber.substring(1) };
        }

        //0
        return new String[] { "0", romanNumber };
    }
}

六、解題方法2

由於上一個方法中存在類似代碼重複使用的狀況,所以能夠嘗試儘可能用數組和循環減小代碼行數。

Java代碼以下:

/**
 * 功能說明:LeetCode 13 - Roman to Integer 
 * 開發人員:Tsybius2014
 * 開發時間:2015年8月3日
 */
public class Solution {

    /**
     * 羅馬數字轉換爲阿拉伯數字
     * @param s 被轉換的羅馬數字
     * @return 轉換後的阿拉伯數字
     */
    public int romanToInt(String s) {

        //羅馬數字 一、五、十、50、100、500、1000
        String romanNumber = "IVXLCDM  ";
        
        String[] temp; //臨時數組
        String result = ""; //計算結果

        //循環千位、百位、十位、個位
        for (int i = 6; i >= 0; i-=2) {
            
            //獲取一、五、10三個數字單位
            String one = romanNumber.substring(i, i + 1);
            String five = romanNumber.substring(i + 1, i + 2);
            String ten = romanNumber.substring(i + 2, i + 3);
            
            temp = getArabicNumber(s, one, five, ten);
            result += temp[0];
            s = temp[1];
        }
        
        return Integer.parseInt(result);
    }
    
    /**
     * 將羅馬數字的首位轉換爲阿拉伯數字(須要指定具體位的一、五、10三個字母)
     * @param romanNumber 羅馬數字
     * @param one 一
     * @param five 五
     * @param ten 十
     * @return 數組
     *     第一項爲輸入羅馬數字中最高位數對應的阿拉伯數字
     *     第二項爲刪去該數字後剩餘部分的羅馬數字 
     */
    private String[] getArabicNumber(String romanNumber, 
        String one, String five, String ten) {

        //羅馬數字的長度
        int[] romanNumber1to9Length = new int[] {
            1, 2, 3, 2, 1, 2, 3, 4, 2
        };
        
        //羅馬數字的構成
        String[] romanNumber1to9 = new String[] {
            one, one + one, one + one + one, one + five, five, 
            five + one, five + one + one, five + one + one + one, one + ten
        };
        
        //1-9的狀況匹配
        for (int i = 9; i >= 1; i--) {
            int len = romanNumber1to9Length[i - 1];
            String num = romanNumber1to9[i - 1];
            if (romanNumber.length() >= len && 
                romanNumber.substring(0, len).equals(num)) {
                return new String[] { 
                    String.valueOf(i), romanNumber.substring(len) 
                };
            }
        }
        
        //無匹配狀況,返回0
        return new String[] { "0", romanNumber };
    }
}

七、解題方法3

雖然羅馬數字的書寫規則較爲複雜,但根據羅馬數字「左加右減」的規律,能夠構造出更簡單的羅馬數字轉換阿拉伯數字的方法:即從右向左(從低位向高位)考察羅馬數字,遇到比上一個數字大的數字就加上,遇到比上一個數字小的數字就減去。

Java代碼以下:

import java.util.HashMap;

/**
 * 功能說明:LeetCode 13 - Roman to Integer 
 * 開發人員:Tsybius2014
 * 開發時間:2015年8月3日
 */
public class Solution {

    /**
     * 羅馬數字轉換爲阿拉伯數字
     * @param s 被轉換的羅馬數字
     * @return 轉換後的阿拉伯數字
     */
    public int romanToInt(String s) {

        HashMap<Character, Integer> hashMap = new HashMap<Character, Integer>();
        
        hashMap.put('I', 1);
        hashMap.put('V', 5);
        hashMap.put('X', 10);
        hashMap.put('L', 50);
        hashMap.put('C', 100);
        hashMap.put('D', 500);
        hashMap.put('M', 1000);
        
        int result = 0; 
        int temp = 0; //臨時變量,用於判斷加減
        int weight = 0; //當前讀取到的羅馬數字的權重
        for (int i = s.length() - 1; i >= 0; i--) {
            weight = hashMap.get(s.charAt(i));
            if (temp <= weight) {
                result += weight;
                temp = weight;
            } else {
                result -= weight;
                temp = weight;
            }
        }
        
        return result;
    }
}

END

相關文章
相關標籤/搜索