2010年3月23日 星期二

基數排序

將一組資料由小而大或由大而小排序式是資料處理中很重要的工作。有一種排序方法稱為基數排序,它的做法是先排數值的個位數,接著排十位數、百位數,千位數、、、。寫一個程式輸入n 筆的數值,並輸出其排序過程。

輸入說明:第一列為數值個數n,(n介於2~10)。
第二列至第n+1列為各數值。(每個數值最多為三位數)
輸入範例:假定有5筆數值分別為:858、792、459、574、762。實際輸入之檔案內容如下:
實際輸入:(test7.txt)
5
858
792
459
574
762

輸出說明:第一列為未排序前的數值次序。
第二列起為各階段排序的數值次序。

輸出範例:上例中5筆數值的各階段排序的數值次序如下:
未排序前:
858、792、459、574、762
第一次依個位數排序結果:
792、762、574、858、459
第二次依十位數排序結果:
858、459、762、574、792
第三次依佰位數排序結果:
459、574、762、792、858

實際輸出:(result7.txt)
858、792、459、574、762
792、762、574、858、459
858、459、762、574、792
459、574、762、792、858

7 則留言:

  1. Dim a(20) As Integer, b(20) As Integer, c(20) As Integer
    Private Sub Form_Load()
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Input #1, n
    For i = 1 To n
    Input #1, a(i)
    Print #2, a(i);
    Next i
    Print #2,
    For k = 1 To 3
    For i = 1 To n
    c(i) = a(i)
    b(i) = Mid(c(i), 4 - k, 1)
    Next i
    For i = 1 To n
    For j = 1 To n
    If b(i) < b(j) Then
    change b(i), b(j)
    change c(i), c(j)
    End If
    Next j
    Next i
    For i = 1 To n
    Print #2, c(i);
    Next i
    Print #2,
    Next k
    Close #1
    Close #2
    End Sub
    Public Sub change(x, y)
    z = x
    x = y
    y = z
    End Sub

    回覆刪除
  2. 阿瑋好,
    這題也是基本的排序的小變形而已。程式OK。
    在練習這類的題目時,也要記得除了排得出來之外,你用的是什麼排序?
    你(們)現在的功力,可以排的方式,有氣泡排序,選擇排序,還有像上次題目中的一定範圍內的記次數排序。
    這樣的題目要試試不同的結果哦。比如這題說是不超過三位數,那你有沒有試試一位數和二位數的狀況呢?(這並不算是「錯誤處理」哦!)

    回覆刪除
  3. Dim Q0(11), Q1(11), Q2(11), Q3(11) As Integer
    Dim ansQ0, ansQ1, ansQ2, ansQ3 As String
    Private Sub Form_Load()
    Open App.Path & "/in.txt" For Input As #1
    Open App.Path & "/out.txt" For Output As #2
    Input #1, n
    For i = 1 To n
    Input #1, Q0(i)
    Q1(i) = Q0(i): Q2(i) = Q0(i): Q3(i) = Q0(i)
    ansQ0 = ansQ0 & Q0(i)
    If i <> n Then ansQ0 = ansQ0 & "、"
    Next i
    Print #2, ansQ0
    For i = 1 To n
    For j = i To n
    a = Mid(Q1(i), 3, 1)
    b = Mid(Q1(j), 3, 1)
    If a > b Then aa = Q1(i): Q1(i) = Q1(j): Q1(j) = aa
    Next j
    ansQ1 = ansQ1 & Q1(i)
    If i <> n Then ansQ1 = ansQ1 & "、"
    Next i
    Print #2, ansQ1
    For i = 1 To n
    For j = i To n
    a = Mid(Q2(i), 2, 1)
    b = Mid(Q2(j), 2, 1)
    If a > b Then aa = Q2(i): Q2(i) = Q2(j): Q2(j) = aa
    Next j
    ansQ2 = ansQ2 & Q2(i)
    If i <> n Then ansQ2 = ansQ2 & "、"
    Next i
    Print #2, ansQ2
    For i = 1 To n
    For j = i To n
    a = Mid(Q3(i), 1, 1)
    b = Mid(Q3(j), 1, 1)
    If a > b Then aa = Q3(i): Q3(i) = Q3(j): Q3(j) = aa
    Next j
    ansQ3 = ansQ3 & Q3(i)
    If i <> n Then ansQ3 = ansQ3 & "、"
    Next i
    Print #2, ansQ3
    Close #2
    Close #1
    End Sub

    我印出來 第四小題的結果是459、574、792、762、858
    跟答案不一樣 但是百位數確實有排序到 不知道這樣行不行?

    回覆刪除
  4. Private Sub Form_Load()
    Dim a(10) As String
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Input #1, x
    For i = 1 To x
    Input #1, w
    a(i) = w
    Print #2, a(i),
    Next i
    Print #2,
    q = 1
    Do Until q = 4
    For i = 1 To x - 1
    For j = i + 1 To x
    If Mid(a(i), 4 - q, 1) > Mid(a(j), 4 - q, 1) Then zxc a(i), a(j)
    Next j
    Next i

    For i = 1 To x
    Print #2, a(i),
    Next i
    Print #2,
    q = q + 1
    Loop
    Print
    Close #1
    Close #2
    End Sub
    Public Sub zxc(q, g)
    c = q
    q = g
    g = c
    End Sub

    回覆刪除
  5. 高仔、阿揚好,
    1.排序,有分會不會影響到原來的順序的方式。
    這題高仔如果結果和例子不同,而假設例子沒打錯的話,那就是高仔要更改程式,讓結果符合例子的結果。
    星期一有試到,例如將 if a>b then 改成 if a>=b then 就有可能改變這個狀況,反之也可能。試試吧。
    2.函數、副程式的參數的寫法,還是正常地用名稱(參數1,參數2)的方式吧。
    函數會傳回值,所以要以數值(或字串)的身分來處理它,像是用 x = ff( a,b)
    而副程式則當成一行指令,用成
    call zxc( a(i), a(j) )

    3.而且,不管是函數還是副程式,如果只在程式中出現一遍,還不如直接寫在原來的程式中,呼叫一次,是會花執行時間的。
    並且,因為可能會是「傳值」或是「值位址」的方式,而造成不同,且不易找出的錯誤。
    所以,阿瑋的這題中的互換的部分,還不如直接寫的好。

    回覆刪除
  6. Dim N(10) As Integer
    Private Sub Form_Load()
    Open App.Path & "\in.txt" For Input As #1
    Open App.Path & "\out.txt" For Output As #2
    Input #1, qqq
    For i = 1 To qqq
    Input #1, N(i)
    Print #2, N(i);
    Next i
    Print #2,
    cot = 10
    For iii = 1 To 3
    For i = 1 To qqq
    a1 = N(i) Mod cot
    For j = 1 To qqq
    a2 = N(j) Mod cot
    If a1 < a2 Then Call cha(N(i), N(j))
    Next j
    Next i
    For i = 1 To qqq
    Print #2, N(i);
    Next i
    Print #2,
    cot = cot * 10
    Next iii
    Close #2
    Close #1
    End Sub
    Public Sub cha(a, b)
    c = a
    a = b
    b = c
    End Sub

    老師
    我這題做出來
    再第三行的地方
    雖然有排序 可是印出來卻是
    858 762 574 459 792
    不知道是錯在哪一點說...
    但是結果印出來卻是正確的
    459 574 762 792 858

    回覆刪除