2011年3月14日 星期一

簡易大數乘法

輸入2個數 N1、N2 。 (0 < N1)、(0 < N2 < 100)

求出N1與N2的乘積。



輸入:
100000000000000
99
輸出:

9900000000000000

9 則留言:

  1. Private Sub Form_Load()
    Dim N1 As String, N2 As String, NS1, NS2, ANS(2) As String, L1 As Integer, L2 As Integer

    Me.Hide

    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2

    Input #1, N1
    Input #1, N2

    For k = Len(N2) To 1 Step -1

    NS2 = Val(Mid(N2, k, 1))
    L1 = 0
    For i = Len(N1) To 0 Step -1

    If i = 0 Then
    ANS(k) = L1 & ANS(k)
    Else
    NS1 = Val(Mid(N1, i, 1))
    L2 = NS1 * NS2
    ANS(k) = ((L2 + L1) Mod 10) & ANS(k)
    L1 = (L2 + L1) \ 10
    End If

    Next
    Next


    Dim S1 As Integer, S2 As Integer, Tmp1 As Integer, Plus As Integer, FAns As String


    If Len(N2) > 1 Then ANS(1) = ANS(1) & "0"
    Do Until Len(ANS(1)) = Len(ANS(2))
    If Len(ANS(1)) > Len(ANS(2)) Then
    ANS(2) = "0" & ANS(2)
    Else
    ANS(1) = "0" & ANS(1)
    End If
    Loop




    For i = Len(ANS(1)) To 0 Step -1
    If i = 0 Then
    FAns = Tmp1 & FAns
    Else
    S1 = Mid(ANS(1), i, 1)
    S2 = Mid(ANS(2), i, 1)
    Plus = S1 + S2
    FAns = ((Plus + Tmp1) Mod 10) & FAns
    Tmp1 = (Plus + Tmp1) \ 10
    End If
    Next

    If Left(FAns, 1) = "0" Then FAns = Right(FAns, Len(FAns) - 2)


    Print #2, FAns
    Close
    Close
    End


    End Sub

    回覆刪除
  2. arro好,
    很好,你總是能很快地利用手邊的資源,去解決問題。
    所以,現在的你,是可以用累積資源的方式,增加自己的功力。
    像這題,如果再加上function的方式,來處理加法,會快些。
    另外,將第2位的乘出來的積,加上1個0的部分,可以放在迴圈內。
    還有,計次迴圈會走到那個數,是預知的,可以利用。
    像For i = Len(N1) To 0 Step -1
    If i = 0 Then
    i一定會走到0的,那不如將迴圈少一次,那個i=0的,直接在迴圈的後頭來做。不用在迴圈內白白判斷那麼多次。

    回覆刪除
  3. Private Sub Form_Load()
    Me.Hide
    Dim a As String
    Dim Mm As String
    Dim Nn As String
    Dim a1(10000) As String
    Open App.Path & "\out.txt" For Output As #2
    Open App.Path & "\in.txt" For Input As #1
    Input #1, Mm, Nn

    For i = 1 To Len(Nn)
    d = Mid(Nn, Len(Nn) + 1 - i, 1)
    f = 0
    For j = Len(Mm) To 1 Step -1
    c = Mid(Mm, j, 1)
    cd = Val(d) * Val(c) + f
    f = cd \ 10
    a1(i) = (cd Mod 10) & a1(i)
    Next j
    If f > 0 Then a1(i) = f & a1(i)
    Next i

    For i = Len(Nn) To 1 Step -1
    strt = Str(10 ^ (i - 1))
    ze = Right(strt, Len(strt) - i)
    If (i - 1) = 0 Then ze = ""
    a1(i) = a1(i) & ze
    Next i

    If Len(Nn) = 1 Or Len(Mm) = 1 Then
    ans = a1(1)
    Else
    For i = 2 To Len(Nn)
    If i = 2 Then
    ans = p(a1(i), a1(i - 1))
    Else
    ans = p(ans, a1(i))
    End If
    Next i
    End If
    Print #2, ans

    Close #1
    Close #2
    End
    End Sub
    Function p(m, n)
    Lenm = Len(m)
    Lenn = Len(n)
    Do Until i > Lenm And i > Lenn
    If Lenm > i Then x = Val(Mid(m, Lenm - i, 1)) Else x = 0
    If Lenn > i Then y = Val(Mid(n, Lenn - i, 1)) Else y = 0
    z = x + y + c
    c = z \ 10
    a = (z Mod 10) & a
    i = i + 1
    If i > Lenm And i > Lenn And (z Mod 10 = 0) Then a = Right(a, Len(a) - 1)
    Loop
    p = a
    End Function

    回覆刪除
  4. 輸入:
    105
    97
    輸出:
    10185
    ----------------------
    還沒習慣貼結果-.-

    回覆刪除
  5. 緣尉好,
    既然是大數乘法,你用了一個這麼小的數是?
    要貼結果,就貼個幾組。小的當成驗算用的,拿一兩個大的,當成好看的。
    說,我可以做100位數乘200位數,得到300位數左右的結果。用算盤、計算機都做不出結果的。

    回覆刪除
  6. Private Sub Form_Load()
    Me.Hide
    Dim a As String
    Dim Mm As String
    Dim Nn As String
    Dim a1(10000) As String
    Open App.Path & "\out.txt" For Output As #2
    Open App.Path & "\in.txt" For Input As #1
    Input #1, Mm, Nn

    For i = 1 To Len(Nn)
    d = Mid(Nn, Len(Nn) + 1 - i, 1)
    f = 0
    For j = Len(Mm) To 1 Step -1
    c = Mid(Mm, j, 1)
    cd = Val(d) * Val(c) + f
    f = cd \ 10
    a1(i) = (cd Mod 10) & a1(i)
    Next j
    If f > 0 Then a1(i) = f & a1(i)
    Next i

    ' For i = Len(Nn) To 1 Step -1
    ' strt = Str(10 ^ (i - 1))
    ' ze = Right(strt, Len(strt) - i)
    ' If (i - 1) = 0 Then ze = ""
    ' a1(i) = a1(i) & ze
    ' Next i

    ' If Len(Nn) = 1 Or Len(Mm) = 1 Then
    ' ans = a1(1)
    ' Else
    'For i = 2 To Len(Nn)
    ' If i = 2 Then
    ' ans = p(a1(i), a1(i - 1))
    ' Else
    ' ans = p(ans, a1(i))
    ' End If
    ' Next i
    ze = ""
    ans = "0"
    For i = 1 To Len(Nn)
    a1(i) = a1(i) & ze
    ans = p(ans, a1(i))
    ze = ze & "0"
    Next i
    If Left(ans, 1) = "0" Then ans = "0"
    Print #2, ans
    Close #1
    Close #2
    End
    End Sub
    Function p(m, n)
    Lenm = Len(m)
    Lenn = Len(n)
    If m = "" Or m = 0 Then m = "0"
    If n = "" Or n = 0 Then n = "0"
    Do Until i > Lenm And i > Lenn
    If Lenm > i Then x = Val(Mid(m, Lenm - i, 1)) Else x = 0
    If Lenn > i Then y = Val(Mid(n, Lenn - i, 1)) Else y = 0
    z = x + y + c
    c = z \ 10
    a = (z Mod 10) & a
    i = i + 1
    If i > Lenm And i > Lenn And (z Mod 10 = 0) Then a = Right(a, Len(a) - 1)
    Loop
    p = a
    End Function
    --------------------------
    輸入
    100000000000000000000000000000000
    9999999999999999999
    輸出
    999999999999999999900000000000000000000000000000000
    輸入
    0
    1486157999999999999999
    輸出
    0

    回覆刪除
  7. Private Sub Form_Load()
    Me.Hide
    Dim a As String, b As String
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2



    Input #1, a
    Input #1, b
    If a = "0" Or b = "0" Then Print #2, "0" Else Print #2, Bmult(a, b)
    Close
    Close
    End
    End Sub

    Function Bmult(A1 As String, A2 As String)
    Dim NS1, NS2, L1 As Integer, L2 As Integer, Ans1 As String, Ans2 As String


    For i = Len(A2) To 1 Step -1
    NS2 = Val(Mid(A2, i, 1))
    L1 = 0: L2 = 0
    For j = Len(A1) To 1 Step -1

    NS1 = Val(Mid(A1, j, 1))

    L2 = NS1 * NS2
    Ans1 = ((L1 + L2) Mod 10) & Ans1
    L1 = (L2 + L1) \ 10

    Next
    Ans1 = L1 & Ans1
    For k = Len(A2) - i To 1 Step -1
    Ans1 = Ans1 & "0"
    Next
    If Left(Ans1, 1) = "0" Then Ans1 = Right(Ans1, Len(Ans1) - 1)
    Ans2 = Bplus(Ans1, Ans2)
    Ans1 = ""
    Next

    Bmult = Ans2

    End Function

    Function Bplus(N1 As String, N2 As String)
    Dim NS1 As Integer, NS2 As Integer, TMP As Integer, Plus As String, FAns As String

    Do Until Len(N1) = Len(N2)
    If Len(N1) > Len(N2) Then
    N2 = "0" & N2
    Else
    N1 = "0" & N1
    End If
    Loop


    For i = Len(N1) To 0 Step -1

    If i = 0 Then
    FAns = TMP & FAns
    Else
    NS1 = Mid(N1, i, 1)
    NS2 = Mid(N2, i, 1)
    Plus = NS1 + NS2
    FAns = ((Plus + TMP) Mod 10) & FAns
    TMP = (Plus + TMP) \ 10
    End If

    Next

    If Left(FAns, 1) = "0" Then FAns = Right(FAns, Len(FAns) - 1)

    Bplus = FAns

    End Function



    ----------

    函數型的大數乘法
    之前寫得有點錯誤

    這次的可以處理任兩正整數而沒有限制位數了

    回覆刪除
  8. 緣尉好,arro好,
    一回生,二回熟,這樣的程式,越寫越順了,很好。
    覺得看你們在前進的感覺,滿好的。要繼續加油。

    回覆刪除
  9. Dim A As String
    Dim B As String
    Private Sub Form_Load()
    Me.Hide
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Input #1, A, B

    If Len(A) > Len(B) Then B = MLEN(B, Len(A))
    If Len(A) < Len(B) Then A = MLEN(A, Len(B))

    Zero = ""
    ans = "0"

    For i = Len(A) To 1 Step -1
    For j = Len(B) To 1 Step -1

    d = Val(Mid(A, i, 1)) * Val(Mid(B, j, 1))

    If d <> 0 Then

    d = d & Zero
    If Len(ans) > Len(d) Then d = MLEN(d, Len(ans))
    If Len(ans) < Len(d) Then ans = MLEN(ans, Len(d))
    ans = Mplus(ans, d)

    End If

    Zero = Zero & "0"

    Next j
    Zero = Left(Zero, Len(A) - i + 1)
    Next i

    Print #2, ans

    Close #2
    Close #1

    End
    End Sub
    Function MLEN(X, Y) '補0 X 為要補數 Y為字長數

    For i = 1 To (Y - Len(X))
    X = "0" & X
    Next i

    MLEN = X

    End Function
    Function Mplus(X, Y)
    go = 0
    ans = ""


    For i = Len(X) To 1 Step -1
    Z = Val(Mid(X, i, 1)) + Val(Mid(Y, i, 1)) + go
    If Z >= 10 Then go = Z \ 10: Z = Z Mod 10 Else go = 0
    ans = Z & ans
    Next i
    If go <> 0 Then ans = go & ans
    Mplus = ans

    End Function

    副程式就像元件需要時拿出來用:D

    回覆刪除