[LeetCode]Integer to Roman

題目:

Integer to Roman

 

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.


來源:http://oj.leetcode.com/problems/integer-to-roman/


思路:

Background:

首先,學習一下羅馬數字,參考羅馬數字

羅馬數字是最古老的數字表示方式,比阿拉伯數組早2000多年,起源於羅馬

羅馬數字有如下符號:
基本字符 I V X L C D M
對應阿拉伯數字 1 5 10 50 100 500 1000
計數規則:
  1. 相同的數字連寫,所表示的數等於這些數字相加得到的數,例如:III = 3
  2. 小的數字在大的數字右邊,所表示的數等於這些數字相加得到的數,例如:VIII = 8
  3. 小的數字,限於(I、X和C)在大的數字左邊,所表示的數等於大數減去小數所得的數,例如:IV = 4
  4. 正常使用時,連續的數字重複不得超過三次
  5. 在一個數的上面畫橫線,表示這個數擴大1000倍(本題只考慮3999以內的數,所以用不到這條規則)
其次,羅馬數字轉阿拉伯數字規則(僅限於3999以內):
最先想到的用switch處理。不過代碼量較大。
後來在查找網絡的時候發現只有4,9是左減,其餘的數字都是右加。所以,構建兩個數組,分別是數字和對應的字母。數字,要把所有的4,9加進來。包括4,9,40,90,400,900.
從前向後遍歷羅馬數字,如果某個數比前一個數小,則加上該數。反之,減去前一個數的兩倍然後加上該數
以及最後網上流行的一個使用vector pair對的方案。

C++ AC代碼:

switch-case方案:

class Solution {
public:
    
    string intToRoman(int num) {
        if(num <= 0 || num >= 4000)
            return NULL;
            
        string roman[] = { "I","V","X","L","C","D","M" };
        string RomanString = "";                    
        while(num != 0)
        {
            int temp = num % 10;
            string Rstr = "";
            switch(temp)
            {
                case 1:
                    Rstr = roman[i];
                    break;
                case 2:
                    Rstr = roman[i] + roman[i];
                    break;
                case 3:
                    Rstr = roman[i] + roman[i] + roman[i];
                    break;
                case 4:
                    Rstr = roman[i] + roman[i+1];
                    break;
                case 5:
                    Rstr = roman[i+1];
                    break;
                case 6:
                    Rstr = roman[i+1] + roman[i];
                    break;
                case 7:
                    Rstr = roman[i+1] + roman[i] + roman[i];
                    break;
                case 8:
                    Rstr = roman[i+1] + roman[i] + roman[i] + roman[i];
                    break;
                case 9:
                    Rstr = roman[i] + roman[i+2];
                    break;
            }
            RomanString = Rstr + RomanString;
            i = i + 2;
            num = num / 10;
        }
        
        
        return RomanString;
    }
};
運行時間 224ms


方案二:

class Solution {
public:
    string intToRoman(int num) {
        int integer[] = { 1000,900,500,400,100,90,50,40,10,9,5,4,1 };
        string roman[] = { "M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I" };
        if(num <= 0 || num >= 4000)
            return NULL;
 
        string RomanString = "";			
        for (int i = 0; i < sizeof(integer)/sizeof(int); ++i){
            while( num >= integer[i] ){
                RomanString += roman[i];
                num -= integer[i]; 
                }   
         }
         return RomanString;
    }
};
運行時間 360ms

使用vector代碼:

class Solution {
public:
    string intToRoman(int num) {
        vector<pair<int, string>> radixes{
        {1000,"M"},
        {900,"CM"},
        {500,"D"},
        {400,"CD"},
        {100,"C"},
        {90,"XC"},
        {50,"L"},
        {40,"XL"},
        {10,"X"},
        {9,"IX"},
        {5,"V"},
        {4,"IV"},
        {1,"I"}
    };
    string roman;
    while(num>0)
    {
        vector<pair<int, string>>::iterator it = radixes.begin();
        //這個for循環很機智
        for(;num / it -> first == 0;it++)
            ;
        for(int i = 0;i < num / it -> first;i++)
            roman += it -> second;
        
        num %= it -> first;
    }
    return roman;
        
    }
};



發佈了55 篇原創文章 · 獲贊 9 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章