日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

string 找出所有数字 index_发现规律,解决整数转罗马数字

發布時間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 string 找出所有数字 index_发现规律,解决整数转罗马数字 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

嗨,各位!我們又準時見面了,即將迎來難得的周末時光,我們今天來一道相對簡單的題目邏輯梳理的題目,原定的動態規劃的常見題型我們放在周末進行更新。話不多說,我們先看題目:? 01 .?題目羅馬數字包含以下七種字符:I, V, X, L,C,D 和 M。
字符數值
I1
V5
X10
L50
C100
D500
M1000
例如,2 寫做 II ,即為兩個并列的 1。12 寫做 XII ,即為 X + II 。27 寫做? XXVII, 即為 XX + V + II 。

通常情況下,羅馬數字中小的數字在大的數字的右邊。但也存在特例,例如 4 不寫做 IIII,而是 IV。數字 1 在數字 5 的左邊,所表示的數等于大數 5 減小數 1 得到的數值 4 。同樣地,數字 9 表示為 IX。

這個特殊的規則只適用于以下六種情況:
  • I 可以放在 V (5) 和 X (10) 的左邊,來表示 4 和 9。
  • X 可以放在 L (50) 和 C (100) 的左邊,來表示 40 和 90。
  • C 可以放在 D (500) 和 M (1000) 的左邊,來表示 400 和 900。

給定一個整數,將其轉為羅馬數字。輸入確保在 1 到 3999 的范圍內。

示例 1: 輸入: 3 輸出: "III" 示例 2: 輸入: 4 輸出: "IV" 示例 3: 輸入: 9 輸出: "IX" 示例 4: 輸入: 58 輸出: "LVIII" 解釋: L = 50, V = 5, III = 3.示例 5: 輸入: 1994 輸出: "MCMXCIV" 解釋: M = 1000, CM = 900, XC = 90, IV = 4.02?. 思路分析這道題整體看起來有明確的規則,只需要梳理清楚羅馬數字的表示規律即可,那我們現在就開始發現規律:跟我們常用的阿拉伯數字表示十進制數字相同,羅馬數字也通過十進制來表示,只是比我們的 0 1 2 3 4 5 的阿拉伯數字復雜一些,而且每一位用的是不同的字母表示。我們先把?0 - 9 的羅馬數字拿出來找規律:
0123456789
IIIIIIIVVVIVIIVIIIIX
我們發現了如下規律:
  • 0?~3? 就是 0 到 3 個?羅馬數字 ‘‘I’’ 表示
  • 4 就是?5 - 1 但是減數放在了前面 既?“IV”
  • 5 ~?8 就是用?一個 羅馬數字 “V”?加上 0 ~ 3?個 羅馬數字 “I” 來表示
  • 9 就是 10 - 1 但是減數放在了前面 既?“IX”
如果我們把每一位數字分為兩組 再去發現規律:
01234
IIIIIIIV
56789
VVIVIIVIIIIX
當 0 ~ 9 我們分別對5取余時,我們發現了更通用的一個規律:
  • 余?0 ~ 3 的時候是:(“空” 或者 “V”?) 加上?余數個“I”

  • 余 4 的時候是:“I” 加上一個 “X”

由此,我們確定了羅馬數字的規律,一個十進制整數的每一位,都涉及到了三個羅馬數字,并按照上述的邏輯去連接羅馬數字即可:

如:個位就是 I V X 三個羅馬數字,十位就是 X L D 三個羅馬數字, 以此類推。到目前為止我們已經發現了具體規律,我們來嘗試著編寫代碼:

/** * @param {number} num * @return {string} */var?intToRoman?=?function(num)?{ let result = [] let unit = ['I', 'V', 'X', 'L', 'C', 'D', 'M'] let index = 0 while(num){ let n = num % 10 let pre = n >= 5 ? unit[index + 1] : '' let u1 = unit[index] let u3 = unit[index + ((n >= 5) ? 2 : 1)] || '' switch (n % 5) { case 1: pre += u1 break case 2: pre += u1 + u1 break case 3: pre += u1 + u1 + u1 break case 4: pre = u1 + u3 break????????} result.push(pre) index += 2 num = Math.floor(num / 10) } return result.reverse().join('')};

這道題目的具體代碼實現比較簡單,我這里就不逐行注釋了,有一個細節需要說明,就是我在處理每一位的時候是用的push()來存入結果數字,在返回答案是先reverse(),在進行數組元素連接成字符串。

原因就是對于同樣的結果操作,push() + reverse() 的操作 比 unshift() 操作快一些,這應該是js的引擎實現決定的,有更深入了解的同學歡迎留言去解釋一下~。

在leetcode上,為了更快的運行結果,還可以用一些預先計算并直接體現在代碼上,因為本題的要求是羅馬數字在1 ~ 3999的范圍,所以羅馬數字組合只有四種,可以直接列出來。我們看一下leetcode上這道題目前最快的代碼示例:

/** * @param {number} num * @return {string} */var intToRoman = function(num) { function TurnFive(n, one, five, ten){ if(n != 0){ if(n < 4){ return one.repeat(n); } if(n == 4){ return one + five; } if(n < 9){ let times = n-5; let I = one.repeat(times) return five + I; } if(n == 9){ return one + ten; } } return ""; } let than = Math.floor(num / 1000); let hon = Math.floor(num % 1000 / 100); let ten = Math.floor(num % 1000 % 100 /10); let ge = Math.floor(num % 1000 %100 % 10); return TurnFive(than, "M", "", "") + TurnFive(hon, "C", "D", "M") + TurnFive(ten, "X", "L", "C") + TurnFive(ge, "I", "V", "X");};

這種針對具體題目的優化在一些online judge的比賽中很常見,不過它的擴展性就會弱一些, 比如 范圍要求是 1 ~3999999 那需要在代碼中直接列出來的內容就有點多了。所以還是發現規律,寫出更通用的代碼才是我們追求的。

這道題到這里就結束了,大家可以自己練練手,最后祝大家周末愉快,明天我會做一個《動態規劃解題的常見題集合》,不過只有一道題會從頭開始分析,剩下的題目只講解思路和特征,也算是給大家留一個聯系的機會,讓大家真是的練練手。

如果你覺得文章的內容能給你帶來收獲,歡迎關注?+?點贊在看?+?轉發,更期待你能推薦給身邊的小伙伴,讓我們一起來梳理前端知識!一起加油!「?往期回顧?」

動態規劃(DP)解積雨問題

動態規劃(DP)解最大連續子序列

文章涉及到源碼已經在github中開源

請在公眾號中發送“源碼”獲取代碼地址

讓我知道你在看

總結

以上是生活随笔為你收集整理的string 找出所有数字 index_发现规律,解决整数转罗马数字的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。