Alpha Camp期末驗收
羅馬數字轉換 Integer to Roman 是Alpha Camp學期2-1期末驗收的其中一題。
除了有查一些語法外,難得有一題全程邏輯都是自己想出來,所以用這篇文章來記錄自己的解題過程
羅馬數字規則
期末驗收的題目規則是:
撰寫一個 toRoman 函式,並假定傳入的數字一定是 1~ 3999 之間的正整數。
在開始前,我們翻開萬能的維基百科了解羅馬數字規則,條列出這次實際會用到的規則:
羅馬數字
羅馬數字共有7個,即I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000)。
標準形式
- 重複數次:一個羅馬數字重複幾次,就表示這個數的幾倍。
- 右加左減:
- 較大的羅馬數字的右邊加上較小的羅馬數字 (如6,VI),表示大數字加小數字。
- 在較大的羅馬數字的左邊加上較小的羅馬數字 (如9,IX),表示大數字減小數字。
- 左減的數字有限制,僅限於I、X、C。比如45是XLV,不用VL。
- 但是,左減時不可跨越一個位值。比如,99是XCIX,不用IC。
- 左減數字必須為一位,比如8是VIII,不用IIX。
- 右加數字不連續超過三位,比如14是XIV,不用XIIII
我的理解
規則乍看有點不太明白,與平常使用的10進位不太一樣。終於明白後我是這麼理解的:羅馬數字規則跟十進位系統有兩個較大的不同
1. 10進位系統中又塞入一個5進位
羅馬數字以5為一個小單位,以1-10的表示方法為例:
(1-5)
- 1、2、3都是透過右加表示,如:1是I、2是II、3是III
- 逢4則用左減表示,4是IV (1在5左邊,所以右邊的5 (V) – 左邊1 (I) = 4)
- 5則直接進位成下一個符號,以 V表示5
(6-0)
- 6、7、8的表示方法跟1-3雷同,都為右加。左邊有個5的基礎上右加, 6是 VI、7是VII、8是VIII
- 9是6到0的第4位數字 (6、7、8、9),需要左減,用 IX 表示9 (1在10左邊,所以右邊的10 (X) – 左邊1 (I) = 4)
- 10跟5一樣,直接進位,以X表示10
2. 每一個位數數字都要獨立表示
像小時候做數學題,我們會將一個數字拆成各個位數,如:143 = 100 + 40 + 3。
羅馬數字也一樣要拆解各個位數,以下舉兩個例子:
143用羅馬數字表示成:CXLIII
C:100、XL:40 (左減,50 – 10)、III:3 (右加三次)
94 會遇到兩次左減,用 XCIV 表示
XC:90 (左減,90 – 10)、IV:4 (左減,5 – 1)
開始程式化
搞懂羅馬數字的規則後,終於要開始將規則寫成程式
Step 0. 將所有會用到的羅馬字母設為變數(陣列)
Step 1. 判斷輸入數字是否符合規則
第一個if/else判斷:是否為數字?是否為整數?是否介於1-3999?若以上判斷都為true,進入下個迴圈。否則跳出正確規則提示。
Step 2. 將數字拆成各個位數
如:143 = 100 + 40 + 3
Step 3. 依照不同範圍數字,設置轉換規則
因為是將數字拆成各個位數轉換成羅馬數字,最後再組裝
因此需要處理兩件事:
- 不同範圍的位數,要給定個別規則
比如數字 1,由於根本沒有 十、百、千位能轉換,所以需要先將十、百、千的變數設為 “”。
不能直接 tens = tensArr[tens – 1], [tens – 1]中的tens這個索引值是null (根本沒有),轉換的結果會是undedined。
- 遇到位數為0時
比如數字103,103會被拆解成:100 + 0 + 3。
透過 tens = tensArr[tens – 1] 轉換時,會索引到「第負1個」 tensArr[0 – 1],造成error。故增加一個判斷:當該位數為0時,將變數設為 “”。
Step 4. 依序組裝各位數字產出的羅馬數字
完整程式碼:Integer to Roman
————–
參考資料:
- 取得各位數字 https://blog.csdn.net/weixin_30917213/article/details/99508916
- 無條件捨去 http://www.eion.com.tw/Blogger/?Pid=1173
- 各位數的變數命名 https://tw.answers.yahoo.com/question/index?qid=20071001000016KK07940
- 判斷是否為整數 https://codertw.com/前端開發/277631/