13 羅馬數字轉整數

2021-10-04 21:46:51 字數 4055 閱讀 4144

羅馬數字包含以下七種字元: i, v, x, l,c,d 和 m。

字元          數值

i 1

v 5

x 10

l 50

c 100

d 500

m 1000

例如, 羅馬數字 2 寫做 iiii

ii,即為兩個並列的 1。12 寫做 xii

xiixi

i ,即為 x+i

ix + ii

x+ii

。 27 寫做 xxv

ii

xxvii

xxvi

i, 即為 xx+

v+ii

xx + v + ii

xx+v+i

i。通常情況下,羅馬數字中小的數字在大的數字的右邊。但也存在特例,例如 4 不寫做 iii

iiiii

iiii

,而是 iviv

iv。數字 1 在數字 5 的左邊,所表示的數等於大數 5 減小數 1 得到的數值 4 。同樣地,數字 9 表示為 ixix

ix。這個特殊的規則只適用於以下六種情況:

給定乙個羅馬數字,將其轉換成整數。輸入確保在 1 到 3999 的範圍內。

示例 1:

輸入:

"iii"

輸出:3

示例 2:

輸入:

"iv"

輸出:4

示例 3:

輸入:

"ix"

輸出:9

示例 4:

輸入:

"lviii"

輸出:58

解釋: l =

50, v=

5, iii =

3.

示例 5:

輸入:

"mcmxciv"

輸出:1994

解釋: m =

1000

, cm =

900, xc =

90, iv =

4.

c的函式原型:

int

romantoint

(char

* s)

題目裡有說,輸入確保在 1 到 3999 的範圍內。

不過這個怎麼判斷呢,使用者輸入的是羅馬數字,而不是阿拉伯數字…

你問我,我也不知道啊。

但可以對輸入引數做檢查。

if

( s ==

null

||*s ==

'\0'

)// 指標是否為null

return

0;

因為只包含了 7 個數字,我們可以建乙個表來對映羅馬數字與阿拉伯數字之間的關係。

int map[90]

=;// 建表, 來對映數字間的關係;大寫字母的範圍是 65(a)-90(z)

字元          數值

i 1

v 5

x 10

l 50

c 100

d 500

m 1000

建表map[

'i']=1

;map[

'v']=5

;map[

'x']=10

;map[

'l']=50

;map[

'c']

=100

;map[

'd']

=500

;map[

'm']

=1000

;

讀了示例後,發現羅馬數字主要有倆種情況(從左往右看):

例如,iviv

iv。i

<

vi < v

i<

v,[前乙個數i

ii] 比 [後乙個數v

vv] 小,就要減掉前乙個數iii。

int

romantoint

(char

* s)

;// 建表, 來對映數字間的關係

map[

'i']=1

; map[

'v']=5

; map[

'x']=10

; map[

'l']=50

; map[

'c']

=100

; map[

'd']

=500

; map[

'm']

=1000

;int roman_val =0;

// 定義乙個變數,儲存羅馬數字轉換後的值

// 倆種情況,分別討論

for(

int i=

0; i<

strlen

(s); i++

)// 從左往右看

if( map[s[i]

]>= map[s[i+1]

])// 左加(前乙個數 >= 後乙個數)

roman_val +

= map[s[i]];

else

// 右減(前乙個數 < 後乙個數)

roman_val -

= map[s[i]];

return roman_val;

}

ac。

查表法的複雜度:

查表法是使用空間換時間,這個題目需要的空間很小,畢竟只有 7 種狀態。

而大部分能使用查表法的題目,可能就需要大量的空間。雖然會讓時間複雜度很好,但占用記憶體太多了。

在時間複雜度上,查表是 θ(1

)\theta(1)

θ(1)

。但是,在真實的計算機中,記憶體和處理器之間還有乙個快取記憶體,程式和資料要先從記憶體進入快取記憶體,才能執行。

快取記憶體的空間非常有限,通常只有幾兆(m

mm),查表占用的記憶體空間可能是快取容量的上千倍,這肯定是放不下的,遇到這種情況,計算機本身要進行上千次額外操作,把記憶體的內容往快取倒騰。

也就是說,如果建立乙個大表,雖然查表只需要做一次,但是準備工作可能要做上千次。

其實划不來,當然,也有一種補救的方法。

把一張大表拆分為幾個小表,每個表查詢一次,再把幾次的相加,雖然查詢次數多了,但占用的記憶體就很少的,這樣就即有查表法的優點(查表時間複雜度是 θ(1

)\theta(1)

θ(1)

),又補救了占用大量記憶體空間的缺陷。

研究【右減】的情況,前乙個數比後乙個數小,就要減掉前乙個數。

而這個規則只適用於以下六種情況:

如果第 i

ii 個元素是 i

ii,第 i+1

i+1i+

1 個元素比第 i

ii 個元素大,那就只有 v、x

v、xv、

x。如果第 i

ii 個元素是 x

xx,第 i+1

i+1i+

1 個元素比第 i

ii 個元素大,那就只有 l、c

l、cl、

c。如果第 i

ii 個元素是 c

cc,第 i+1

i+1i+

1 個元素比第 i

ii 個元素大,那就只有 d、m

d、md、

m。

int

romantoint

(char

* s)

return count;

}

過程模擬複雜度:

13 羅馬數字轉整數

羅馬數字包含以下七種字元 i,v,x,l,c,d和m。字元 數值 i 1 v 5 x 10 l 50 c 100 d 500 m 1000例如,羅馬數字 2 寫做ii,即為兩個並列的 1。12 寫做xii,即為x ii。27 寫做xxvii,即為xx v ii。通常情況下,羅馬數字中小的數字在大的數...

13 羅馬數字轉整數

羅馬數字包含以下七種字元 i,v,x,l,c,d和m。字元 數值i 1 v 5 x 10 l 50 c 100 d 500 m 1000例如,羅馬數字 2 寫做ii,即為兩個並列的 1。12 寫做xii,即為x ii。27 寫做xxvii,即為xx v ii。通常情況下,羅馬數字中小的數字在大的數字...

13 羅馬數字轉整數

羅馬數字包含以下七種字元 i,v,x,l,c,d 和 m。字元 數值 i 1 v 5 x 10 l 50 c 100 d 500 m 1000 例如,羅馬數字 2 寫做 ii 即為兩個並列的 1。12 寫做 xii 即為 x ii 27 寫做 xxvii,即為 xx v ii 通常情況下,羅馬數字中...