Python 羅馬數字與阿拉伯數字的轉換

2021-08-03 04:13:06 字數 3436 閱讀 8097

原文

複雜度o(n)

在看《dive into python》的單元測試時,發現用作例子的「阿拉伯數字-羅馬數字」的轉換演算法非常的巧妙,現在發上來和大家分享一下。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

romannumeralmap = (('m',1000),

('cm',900),

('d',500),

('cd',400),

('c',100),

('xc',90),

('l',50),

('xl',40),

('x',10),

('ix',9),

('v',5),

('iv',4),

('i',1))

def toroman(n):

result = ""

for numeral, integer in romannumeralmap:

while n >= integer:

result += numeral

n -= integer

return result

def fromroman(s):

result = 0

index = 0

for numeral, integer in romannumeralmap:

while s[index:index+len(numeral)] == numeral:

result += integer

index += len(numeral)

return result

print toroman(1356)

print fromroman('mcmlxxii')

這個演算法的聰明之處,就在於他通過乙個romannumeralmap,把羅馬數字與阿拉伯數字裡面的「邊界值」做出一一對應。這個邊界剛剛好是羅馬數字組合之間的轉換。例如,i,ii,iii都可以通過第乙個邊界值組合獲得;v,vi,vii,viii可以通過v和i的組合獲得。而對於一些特殊的值,則直接列出來。例如iv。通過這個邊界值的組合,就能實現所需求的轉換。這就類似於在一些機讀卡上,需要填寫1到100的數字,他會使用0,1,2,4,7這樣以來:

1

2

3

4

5

3 = 1 + 2;

5 = 4 + 1;

6 = 4 + 2;

8 = 7 + 1;

9 = 7 + 2.

首先看一下toroman()函式,把阿拉伯數字轉換成羅馬數字。它使用python連線字串的操作符號 + 來使「邊界值」連線到一起。例如用作例子的n = 1356,程式遍歷romannumeralmap,尋找n對應的羅馬數字,如果找不到,那就找剛剛比n小一點的數字對應的羅馬字元。遍歷在能使n 在romannumeralmap有對應值時結束。

找到剛剛比1356小的那個值對應的羅馬數字,也就是1000,m

再繼續找剛剛比n = 1356 - 1000 = 356小的數,也就是100,c;

又繼續找比n = 356 - 100 = 256小的數,還是100,也就是c;

再找比n = 256 - 100 = 156小的數,仍然是100,c;

繼續找比n = 156 - 100 = 56 小的數,50,l;

繼續找比n = 56 - 50 = 6小的數,5,v;

繼續找n = 6 - 5 = 1對於的數,1,i。 結束。

所以1356對應的值為mccclvi。 這樣的操作很類似於在十進位制裡面,乙個數字1356 = 1000 + 300 + 50 + 6,只是阿拉伯數字裡面6是乙個單獨的符號,而羅馬數字裡面vi是個v + i的組合而已。

下面再說說fromroman()函式,把羅馬數字轉換成阿拉伯數字。這個函式在理解上面可能比toroman()稍稍要困難一點。

還是用例子來說明,mcmlxxii轉換成阿拉伯數字。

其中如下**

1

s[index:index+len(numeral)]

作用是把字串s中,從第index位到第index+ len(numeral)位(不包含第index + len(numeral)位自身)的字元提取出來。比如:

>>> a = 'helloworld'

>>> print a[2:5]

llo

即s的第2,3,4位被取出。

回到對s = 『mcmlxxii』的處理。

首先map中第乙個羅馬字元是m,只有一位,就把s 的第0位拿出來對比,發現s的第0位剛剛好是m,於是得到乙個1000,index變為1,則之後從s的第一位開始。簡單的說,相當於s 變成了s = 'cmlxxii'

接下來,經過一些無效的值以後,輪換到cm,發現cm為兩位,就取出s的前兩位,也就是cm,發現在s中剛剛好有cm,於是得到900. index再加2,則實際上s就相當於變成了lxxii

繼續經過一些無效值以後,輪換到了l,發現s當前的1位為l,於是在map中有對應的值50.然後index加1,s相當於變成了xxii

接下來到了x,發現s當前的1位為x,在map中有對應的值10.然後index 再加1,s變成了xii

雖然這個時候人已經知道是12了,但是計算機還是不知道,於是繼續乙個x,s變為ii

然後出現乙個i,s變為i

終於程式找到了乙個直接相等的值i,於是轉換結束。

所以mcmlxxii對於的阿拉伯數字是1000+900+50+10+10+1+1 = 1972

這個方法,把乙個羅馬數字從高位開始逐次剝離最高位,從而漸漸的把數字縮小。

最近正在學習演算法。因為越來越發現現在做的東西,如果僅僅實現功能的話,效能會出現瓶頸。希望我以後能寫出更好的演算法。

阿拉伯數字轉羅馬數字

最開始想的是當成進製轉,比如說 1 i,2 ii,5 v,6 vi public static string inttoroman1 int num int radix stringbuffer sb new stringbuffer for int i radix.length 1 i 0 i r...

阿拉伯數字轉羅馬數字

時間限制 c c 1秒,其他語言2秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld 題目描述 張老師需要用數字來統計學生們的得分情況,但阿拉伯數字已經不能滿足他的要求了,所以想請你幫忙將學生的成績轉換成羅馬數字。羅馬數字是由七個不同的符號來表示 i...

羅馬數字轉阿拉伯數字

羅馬數字轉阿拉伯數字 1.羅馬數字是位置計數嗎?它的缺點是什麼?答 不是,缺點有規則複雜,書寫不便,沒有數字0 羅馬數字包含以下七種字元 i,v,x,l,c,d 和 m。python 字元 數值 i 1 v 5 x 10 l 50 c 100 d 500 m 1000 2.將學號20191210轉為...