羅馬數字包含以下七種字元: 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 通常情況下,羅馬數字中...