2012年7月12日 星期四

羅馬數字

設計一程式可將最長含10個字元的字串讀入, 每一個字元均代表某一數值的羅馬數表示法。將讀入之羅馬數及其相對應之阿拉伯數一起列印出來。
【壹】 羅馬數和字元之對應表如下: 

M 1000 

D 500 

C 100 

L 50 

X 10 

V 5 

I 1 
你的輸入有下列幾組: 

(1) VII 

(2) LXXXVII 

(3) CCXIX 

(4) MCCCLIV 

(5) MMDCLXXIII 

(6) MCDLXXVI

8 則留言:

  1. Private Sub Form_Load()
    Me.Hide
    Dim ans As Long
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Do While Not EOF(1)
    ans = 0
    Line Input #1, X1
    M = 1000
    D = 500
    C = 100
    L = 50
    x = 10
    V = 5
    i = 1
    For i = 5 To Len(X1)
    If Mid(X1, i, 1) = "M" Then ans = ans + 1000
    If Mid(X1, i, 1) = "D" Then ans = ans + 500
    If Mid(X1, i, 1) = "C" Then ans = ans + 100
    If Mid(X1, i, 1) = "L" Then ans = ans + 50
    If Mid(X1, i, 1) = "X" Then ans = ans + 10
    If Mid(X1, i, 1) = "V" Then ans = ans + 5
    If Mid(X1, i, 1) = "I" Then ans = ans + 1
    Next
    Print #2, ans
    Loop
    Close
    Close
    End
    End Sub

    回覆刪除
  2. 小冰好,
    在羅馬數字中,
    XI=11
    IX=9
    所以,I擺在字串中,應該是減,所以你這題錯誤了。
    (看到你們的7月的題目,暴增之後,旅行的心情大好,加油,希望是自己給的,累積出自己的未來吧!)
    熊掌 Paris

    回覆刪除
  3. Private Sub Form_Load()
    Me.Hide
    Dim ans As Long
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Do While Not EOF(1)
    ans = 0
    Line Input #1, X1
    M = 1000
    D = 500
    C = 100
    L = 50
    x = 10
    V = 5
    i = 1
    For j = 5 To Len(X1)
    If Mid(X1, j, 1) = "M" Then
    ans = ans + 1000
    If Mid(X1, j - 1, 1) = "C" Then ans = ans - 200
    End If
    If Mid(X1, j, 1) = "D" Then
    ans = ans + 500
    If Mid(X1, j - 1, 1) = "C" Then ans = ans - 200
    End If
    If Mid(X1, j, 1) = "C" Then
    ans = ans + 100
    If Mid(X1, j - 1, 1) = "X" Then ans = ans - 20
    End If
    If Mid(X1, j, 1) = "L" Then
    ans = ans + 50
    If Mid(X1, j - 1, 1) = "X" Then ans = ans - 20
    End If
    If Mid(X1, j, 1) = "X" Then
    ans = ans + 10
    If Mid(X1, j - 1, 1) = "I" Then ans = ans - 2
    End If
    If Mid(X1, j, 1) = "V" Then
    ans = ans + 5
    If Mid(X1, j - 1, 1) = "I" Then ans = ans - 2
    End If
    If Mid(X1, j, 1) = "I" Then ans = ans + 1
    Next
    Print #2, ans
    Loop
    Close
    Close
    End
    End Sub

    輸入:
    (1) VII

    (2) LXXXVII

    (3) CCXIX

    (4) MCCCLIV

    (5) MMDCLXXIII

    (6) MCDLXXVI
    輸出:
    7
    87
    219
    1354
    2673
    1476

    這樣應該就不會錯了,有查過規則。
    右加左減:
    在較大的羅馬數字的右邊記上較小的羅馬數字,表示大數字加小數字。
    在較大的羅馬數字的左邊記上較小的羅馬數字,表示大數字減小數字。
    但是,左減時不可跨越一個位數。比如,99不可以用IC()表示,而是用XCIX((100-10)+(10-1))表示。(等同於阿拉伯數字每位數字分別表示。)
    此外,左減數字必須為一位,比如8寫成Ⅷ,而非IIⅩ。
    同理,右加數字不可超過三位,比如14寫成ⅩⅣ,而非ⅩⅢⅠ。

    回覆刪除
  4. 小冰好,
    程式正確。
    很好。
    那麼,再反過來呢?
    輸入年份,可以輸出羅馬數字呢?
    今年2012
    MMXII
    ?
    巴黎的熊掌,在吃藍莓。

    回覆刪除
  5. Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Do While Not EOF(1)
    ans = ""
    a = 0
    Input #1, n
    If Len(n) <> 4 Then n = "0" & n
    If Len(n) = 4 Then
    For j = 1 To n \ 1000
    ans = ans & "M"
    Next
    '--------------------------------
    If Mid(n, 2, 1) = 9 Then ans = ans & "CM"
    If Mid(n, 2, 1) = 5 Then ans = ans & "D"
    If Mid(n, 2, 1) > 5 And Mid(n, 2, 1) <> 9 Then
    ans = ans & "D"
    a = Val(Mid(n, 2, 1)) - 5
    For j = 1 To a
    ans = ans & "C"
    Next
    End If
    '---------------------------------
    If Mid(n, 2, 1) < 5 And Mid(n, 2, 1) <> 4 And Mid(n, 2, 1) <> 0 Then
    For j = 1 To Mid(n, 2, 1)
    ans = ans & "C"
    Next
    End If
    If Mid(n, 2, 1) = 4 Then ans = ans & "CD"
    '---------------------------------
    If Mid(n, 3, 1) = 9 Then ans = ans & "XC"
    If Mid(n, 3, 1) > 5 And Mid(n, 3, 1) <> 9 Then
    ans = ans & "L"
    a = Val(Mid(n, 3, 1)) - 5
    For j = 1 To a
    ans = ans & "X"
    Next
    End If
    If Mid(n, 3, 1) = 5 Then ans = ans & "L"
    '---------------------------------
    If Mid(n, 3, 1) < 5 And Mid(n, 3, 1) <> 4 And Mid(n, 3, 1) <> 0 Then
    For j = 1 To Mid(n, 3, 1)
    ans = ans & "X"
    Next
    End If
    If Mid(n, 3, 1) = 4 Then ans = ans & "XL"
    '---------------------------------
    If Mid(n, 4, 1) = 9 Then ans = ans & "IX"
    If Mid(n, 4, 1) = 5 Then ans = ans & "V"
    If Mid(n, 4, 1) > 5 And Mid(n, 4, 1) <> 9 Then
    a = Val(Mid(n, 4, 1)) - 5
    ans = ans & "V"
    For j = 1 To a
    ans = ans & "I"
    Next
    End If
    '---------------------------------
    If Mid(n, 4, 1) < 5 And Mid(n, 4, 1) <> 4 And Mid(n, 4, 1) <> 0 Then
    For j = 1 To Mid(n, 4, 1)
    ans = ans & "I"
    Next
    End If
    If Mid(n, 4, 1) = 4 Then ans = ans & "IV"
    Print #2, ans
    End If
    Loop
    Close
    Close
    End
    End Sub

    這應該就是用數字轉羅馬數字了
    輸入:
    1999
    1966
    2000
    1750
    555
    444
    333
    666
    777
    999
    輸出:
    MCMXCIX
    MCMLXVI
    MM
    MDCCL
    DLV
    CDXLIV
    CCCXXXIII
    DCLXVI
    DCCLXXVII
    CMXCIX

    但僅限3000年以內

    回覆刪除
  6. 4000年以上 那些羅馬數字上就多了一橫
    而這裡顯示不出來
    VB6.0也顯示不出來 因此 最多是3899年

    感冒有好點嗎?

    回覆刪除
  7. 發現一個錯誤,只注意到3位數,沒注意到2位數以及1位數。
    修改後:

    Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Do While Not EOF(1)
    ans = ""
    a = 0
    Input #1, n
    If Len(n) = 1 Then n = "000" & n
    If Len(n) = 2 Then n = "00" & n
    If Len(n) = 3 Then n = "0" & n
    If Len(n) = 4 Then
    If n \ 1000 <= 3 Then
    For j = 1 To n \ 1000
    ans = ans & "M"
    Next
    Else
    Exit Do
    End If
    '--------------------------------
    If Mid(n, 2, 1) = 9 Then ans = ans & "CM"
    If Mid(n, 2, 1) = 5 Then ans = ans & "D"
    If Mid(n, 2, 1) > 5 And Mid(n, 2, 1) <> 9 Then
    ans = ans & "D"
    a = Val(Mid(n, 2, 1)) - 5
    For j = 1 To a
    ans = ans & "C"
    Next
    End If
    '---------------------------------
    If Mid(n, 2, 1) < 5 And Mid(n, 2, 1) <> 4 And Mid(n, 2, 1) <> 0 Then
    For j = 1 To Mid(n, 2, 1)
    ans = ans & "C"
    Next
    End If
    If Mid(n, 2, 1) = 4 Then ans = ans & "CD"
    '---------------------------------
    If Mid(n, 3, 1) = 9 Then ans = ans & "XC"
    If Mid(n, 3, 1) > 5 And Mid(n, 3, 1) <> 9 Then
    ans = ans & "L"
    a = Val(Mid(n, 3, 1)) - 5
    For j = 1 To a
    ans = ans & "X"
    Next
    End If
    If Mid(n, 3, 1) = 5 Then ans = ans & "L"
    '---------------------------------
    If Mid(n, 3, 1) < 5 And Mid(n, 3, 1) <> 4 And Mid(n, 3, 1) <> 0 Then
    For j = 1 To Mid(n, 3, 1)
    ans = ans & "X"
    Next
    End If
    If Mid(n, 3, 1) = 4 Then ans = ans & "XL"
    '---------------------------------
    If Mid(n, 4, 1) = 9 Then ans = ans & "IX"
    If Mid(n, 4, 1) = 5 Then ans = ans & "V"
    If Mid(n, 4, 1) > 5 And Mid(n, 4, 1) <> 9 Then
    a = Val(Mid(n, 4, 1)) - 5
    ans = ans & "V"
    For j = 1 To a
    ans = ans & "I"
    Next
    End If
    '---------------------------------
    If Mid(n, 4, 1) < 5 And Mid(n, 4, 1) <> 4 And Mid(n, 4, 1) <> 0 Then
    For j = 1 To Mid(n, 4, 1)
    ans = ans & "I"
    Next
    End If
    If Mid(n, 4, 1) = 4 Then ans = ans & "IV"
    Print #2, ans
    End If
    Loop
    Close
    Close
    End
    End Sub

    回覆刪除
  8. Dim a(7, 2), b(), c() As Variant
    Dim ans, f As Integer
    Private Sub Form_Load()
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    b = Array("M", "D", "C", "L", "X", "V", "I")
    c = Array(1000, 500, 100, 50, 10, 5, 1)
    For i = 1 To 7
    For j = 1 To 2
    If j = 1 Then a(i, j) = b(i - 1)
    If j = 2 Then a(i, j) = c(i - 1)
    Next j
    Next i
    Do While Not EOF(1)
    Input #1, x
    ans = 0: f = 0: y = StrReverse(x)
    For i = 1 To Len(y)
    Call d(Mid(y, i, 1))
    Next i
    Print #2, ans
    Loop
    Close #2
    Close #1
    End
    End Sub
    Sub d(e)
    For i = 1 To 7
    If e = a(i, 1) Then
    If a(i, 2) < f Then
    If ans > a(i, 2) Then ans = ans - a(i, 2): f = a(i, 2): Exit Sub
    ans = a(i, 2) - ans: f = a(i, 2): Exit Sub
    Else
    ans = ans + a(i, 2): f = a(i, 2): Exit Sub
    End If
    End If
    Next i
    End Sub

    回覆刪除