2010年1月28日 星期四

2010/01/28 平均數、眾數

用亂數產生一個含有50個整數的數列,該數列中之各元素值範圍在170到180之間(包含170與180),請由小到大逐一在螢幕上顯示(以10為一組,分列印出),並列印出此數列之平均數、眾數及此眾數出現之次數。
說明:平均數為所有數之總和除以數列之元素各數
     眾數則是此數列中,出現次數最多的數(若有兩個以上的眾數,則逐一列出)

出自  程式設計隊訓練教材  NO.14 平均數、眾數

18 則留言:

  1. 這題其實和我們在儲備選手試卷的第三題是類似的。
    用高仔的方式,皓的方式都好,松鼠的方式,多做了迴圈。
    阿瑋的方式也是好的。
    試試吧。

    回覆刪除
  2. 平均數應該是/50吧@@

    Dim a(50) As Integer
    Dim b(11) As Integer
    Dim c(11) As Integer
    Dim sum As Long
    Private Sub Form_Load()
    Randomize Timer

    For i = 1 To 50
    a(i) = 169 + Int(Rnd() * 11 + 1)
    sum = sum + a(i)
    Next i
    sum = sum / 50

    For i = 1 To 11
    b(i) = 169 + i
    Next i

    For i = 1 To 49
    For j = i To 50
    If a(i) > a(j) Then
    change a(i), a(j)
    End If
    Next j
    Next i

    For i = 1 To 50
    For j = 1 To 11
    If a(i) = b(j) Then c(j) = c(j) + 1
    Next j
    Next i

    For i = 1 To 10
    For j = i To 11
    If c(i) < c(j) Then
    change c(i), c(j)
    change b(i), b(j)
    End If
    Next j
    Next i

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

    For i = 0 To 4
    For j = 1 To 10
    Print #2, a(j + i * 10);
    Next j
    Print
    Next i

    Print #2, "平均數: " & sum

    Print #2, "眾數: " & b(1) & " " & c(1),

    For i = 2 To 11
    If c(i) = c(1) Then
    Print #2, b(i) & " " & c(i)
    End If
    Next i
    Close #2

    End Sub
    Public Sub change(x, y)
    z = x
    x = y
    y = z
    End Sub

    回覆刪除
  3. Private Sub Form_Load()
    Open App.Path & "out.txt" For Output As #1
    Randomize Timer
    Dim xx(170 To 180) As Byte
    Dim yy(170 To 180) As Byte
    Dim group(50) As Byte
    Dim team(5) As Byte
    Dim staff(10) As Byte
    Dim sum%
    For i = 170 To 180
    xx(i) = 0 + i
    Next i
    Max = yy(170)
    For i = 1 To 50
    group(i) = Int(170 + Rnd * 11)
    If xx(group(i)) = group(i) Then
    yy(group(i)) = yy(group(i)) + 1
    If yy(group(i)) > Max Then
    Max = yy(group(i))
    Maxnum = group(i)
    End If
    End If
    sum = sum + group(i)
    Next i
    sum = sum / 50
    For i = 1 To 49
    For j = i To 50
    If group(i) > group(j) Then
    change group(i), group(j)
    End If
    Next j
    If i Mod 10 = 0 Then
    Print #1, group(i)
    Else
    Print #1, group(i);
    End If
    Next i
    Print #1, group(50)
    Print #1, "平均數" & sum

    For i = 170 To 180
    If yy(i) = Max Then
    Print #1, "眾數" & xx(i) & "有" & Max & "個"
    End If
    Next i
    Close #1
    End Sub
    Public Sub change(a, b)
    x = a
    a = b
    b = x
    End Sub

    回覆刪除
  4. 阿瑋好,
    這次的程式,迴圈多了些。多了些不必要的迴圈,不過,程式是正確的。很好。

    Y揚好,
    1.定義陣列時,很小心地用了byte,但是我想,這應該是不必要的,用一般的integer就好了。
    當然,byte比integer小,應該是比較好的。
    但是,用了170 to 180 這個陣列索引,超好。其它人要學起來。
    2.xx(i)這個陣列,也是不必要的。
    3.if xx(group(i))=group(i) then
    這一行也是不必要的,這是一定的,不是嗎?你的計次,就直接用
    yy(group(i))=yy(group(i)) +1
    這行就可以了吧。本來就是該要用這個方式,要學起來。
    4.在第一個迴圈1 to 50之中,就跑完了(亂數、計次、找最多次、總和)這四件事,超好,要學。
    5.而且,在排序的雙迴圈中,還利用「選擇排序」的特性,順道將已經排好的數,給顯示出來。這是很好的。
    所以,Y揚這次的程式,優點很多哦。

    只是,問題來了,這個好像是「隊長」的問題囉。(哦,對不起啦,這應該是老師的問題才是,sorry)。
    輸出說的不清不楚,說是「在螢幕顯示」,又說列印出平均數、眾數...,
    於是是要像以前一樣輸出在「out.txt」這個檔案嗎?
    要在輸出的時候顯示"平均數:""眾數:"這些說明嗎?

    *請注意,如果不符合題目說明的,你做得再多都「0」分哦,很可怕的。
    *咱們學校的選手,曾有兩屆以上的選手,敗在這個上面,寫的程式比人家好,但是,反正就是0分。不是扣幾分,名次後退個一兩名之類的,而是「0」分,直接就沒有名哦。很可怕的。

    回覆刪除
  5. 再恐嚇一下你們好了,
    簡單講,上面的兩個程式似乎都是正確,但是,輸出的東西不一樣,
    反正,你們兩個至少有一個是0分。
    0分。0分。0分。

    回覆刪除
  6. 照老師的修正改好了 XX陣列真的多加了@@

    Private Sub Form_Load()
    Open App.Path & "out.txt" For Output As #1
    Randomize Timer
    Dim yy(170 To 180) As Byte
    Dim group(50) As Byte
    Dim team(5) As Byte
    Dim staff(10) As Byte
    Dim sum%
    Max = yy(170)
    For i = 1 To 50
    group(i) = Int(170 + Rnd * 11)

    yy(group(i)) = yy(group(i)) + 1
    If yy(group(i)) > Max Then
    Max = yy(group(i))
    Maxnum = group(i)
    End If

    sum = sum + group(i)
    Next i
    sum = sum / 50
    For i = 1 To 49
    For j = i To 50
    If group(i) > group(j) Then
    change group(i), group(j)
    End If
    Next j
    If i Mod 10 = 0 Then
    Print #1, group(i)
    Else
    Print #1, group(i);
    End If
    Next i
    Print #1, group(50)
    Print #1, "平均數" & sum

    For i = 170 To 180
    If yy(i) = Max Then
    Print #1, "眾數" & i & "有" & Max & "個"
    End If
    Next i
    Close #1
    End Sub
    Public Sub change(a, b)
    x = a
    a = b
    b = x
    End Sub

    回覆刪除
  7. Y揚好,
    1.改了很好,但是
    Dim team(5) As Byte
    Dim staff(10) As Byte
    這兩行呢?
    2.dim sum%
    ->
    dim sum as integer
    的方式比較好。

    回覆刪除
  8. 作者已經移除這則留言。

    回覆刪除
  9. Private Sub Form_Load()
    Randomize Timer
    For i = 0 To 49
    a(i) = Int(Rnd() * 11) + 170
    b(a(i)) = b(a(i)) + 1
    Sum = Sum + a(i)
    Next i
    For i = 0 To 49
    For j = 0 To 50
    If a(i) < a(j) Then change a(j), a(i)
    Next j
    Next i
    For i = 170 To 180
    If b(i) > Max Then Max = b(i)
    Next i
    x = 1
    For i = 0 To 10
    If b(i + 170) = Max Then Numax(x) = i + 170: x = x + 1
    Next i
    Open App.Path & "/out.txt" For Output As #2
    For i = 0 To 49
    If i Mod 10 = 9 Then
    Print #2, a(i)
    Else
    Print #2, a(i);
    End If
    Next i
    Print #2, "平均數:" & Sum / 50
    Print #2, "眾數:";
    For i = 1 To 10
    If Numax(i) = 0 Then Print #2,: Exit For
    Print #2, Numax(i);
    Next i
    Print #2, "眾數出現次數:" & Max
    Close #2
    End Sub

    Public Sub change(x, y)
    z = x
    x = y
    y = z
    End Sub
    跟"文字串排序"那題一樣
    訓練教材上並沒有顯示出範例
    完成的比較晚 所以沒有打上完成範例
    真是不好意思 >"<

    回覆刪除
  10. 高仔好,
    1.你這題沒定義a,b陣列,執行時會出錯吧。
    2.這一題,你們都用了「排序」為了印出由小到大。
    其實呢,你們這樣做,並不是題目想要的。
    怪了吧,不排序,怎麼印出由小到大呢?
    想一想。
    3.這一題,如果不是50個亂數,而是5千個、5萬個,就很有差別了哦,因為個數一多,一般的排序,可是很慢的哦。
    以5000個來說,一排序,可是要有25000000次比大小哦,那是2千5百萬次呢,可怕的呢。
    4.所以,這一題,請也試試不用排序的方式,再做一次吧。

    回覆刪除
  11. Dim R(50) As Integer
    Dim A(5) As String
    Dim D(11) As Integer
    Dim sumR As Long
    Dim P(11) As Integer
    Private Sub Form_Load()
    Open App.Path & "\out.txt" For Output As #1
    Randomize Timer
    For i = 1 To 50
    R(i) = 170 + Int(Rnd * 11)
    Select Case R(i)
    Case 170
    D(1) = D(1) + 1
    P(1) = 170
    Case 171
    D(2) = D(2) + 1
    P(2) = 171
    Case 172
    D(3) = D(3) + 1
    P(3) = 172
    Case 173
    D(4) = D(4) + 1
    P(4) = 173
    Case 174
    D(5) = D(5) + 1
    P(5) = 174
    Case 175
    D(6) = D(6) + 1
    P(6) = 175
    Case 176
    D(7) = D(7) + 1
    P(7) = 176
    Case 177
    D(8) = D(8) + 1
    P(8) = 177
    Case 178
    D(9) = D(9) + 1
    P(9) = 178
    Case 179
    D(10) = D(10) + 1
    P(10) = 179
    Case 180
    D(11) = D(11) + 1
    P(11) = 180
    End Select
    sumR = sumR + R(i)
    Next i
    For i = 1 To 11
    Print D(i)
    Next i
    sumR = sumR / 50
    For i = 1 To 49
    For j = i To 50
    If R(i) > R(j) Then change R(i), R(j)
    Next j
    Next i
    For i = 1 To 5
    For j = 1 To 10
    A(i) = A(i) & " " & R(i * j)
    Next j
    Next i
    For i = 1 To 5
    Print A(i)
    Next i
    MinD = 0
    S = 0
    Q = 0
    MinQ = 0
    For i = 1 To 11
    If D(i) > MinD Then
    MinD = D(i)
    If D(i) = MinD And S <> 0 Then
    Q = S
    MinQ = MinD
    End If
    S = i
    End If
    Next i
    Print "平均數" & sumR
    Print "眾數" & P(S) & "有" & MinD & "個"
    If Q <> 0 Then
    Print "眾數" & P(Q) & "有" & MinD & "個"
    End If
    Close #1
    End Sub


    Public Sub change(x, y)
    B = x
    x = y
    y = B
    End Sub


    老師
    這題阿,我想了很久 還是不知到中間哪裡錯了
    像是:排序 沒辦法完全排序完成
    每次程式跑出結果,都只是每一行排序排好
    可是卻其他行卻還是會有第一還出現過的數字
    例如:
    170 171 171 171 171 172 172 172 172 172
    171 171 172 172 172 172 173 173 174 174
    171 172 172 172 173 174 174 174 175 176
    171 172 172 173 174 174 175 176 176 178
    171 172 173 174 174 176 176 178 179 180
    第一行有171 可是第二還卻還是有171
    然後
    我有先計算每一個數字 各出現了幾個
    可是在後面 要印出結果
    卻總會亂掉
    例如:
    眾數172有8個
    眾數171有8個
    這邊我就不太知道要怎麼寫了
    雖然有參考阿楊阿緯高仔的程式
    卻還是看不太懂

    回覆刪除
  12. 小白好,
    首先,
    Select Case R(i)
    Case 170
    D(1) = D(1) + 1
    P(1) = 170
    Case 171
    D(2) = D(2) + 1
    P(2) = 171
    Case 172
    D(3) = D(3) + 1
    P(3) = 172
    Case 173
    D(4) = D(4) + 1
    P(4) = 173
    Case 174
    D(5) = D(5) + 1
    P(5) = 174
    Case 175
    D(6) = D(6) + 1
    P(6) = 175
    Case 176
    D(7) = D(7) + 1
    P(7) = 176
    Case 177
    D(8) = D(8) + 1
    P(8) = 177
    Case 178
    D(9) = D(9) + 1
    P(9) = 178
    Case 179
    D(10) = D(10) + 1
    P(10) = 179
    Case 180
    D(11) = D(11) + 1
    P(11) = 180
    End Select

    這麼一大堆,其實只有一行就可以了:

    a(i) = Int(Rnd() * 11) + 170
    b(a(i)) = b(a(i)) + 1

    的第二行。
    再問問高仔吧。

    回覆刪除
  13. Dim a(50) As Integer, b(50) As Integer, c(11) As Integer
    Private Sub Form_Load()
    Open App.Path & "/out.txt" For Output As #2
    For i = 1 To 50
    a(i) = Int(Rnd() * 11 + 1) + 169
    b(i) = a(i) - 170
    Sum = Sum + a(i)
    Next i
    For i = 1 To 11
    k = 1
    Do Until k = 51
    If b(k) = i - 1 Then
    c(i) = c(i) + 1
    End If
    k = k + 1
    Loop
    Next i
    For i = 1 To 49
    For j = i To 50
    If a(i) > a(j) Then x = a(i): a(i) = a(j): a(j) = x
    Next j
    Next i
    For i = 1 To 50
    Print #2, a(i);
    If i Mod 10 = 0 Then
    Print #2,
    End If
    Next i
    MaxN = 1
    For i = 11 To 1 Step -1
    If c(i) >= MaxN Then MaxN = c(i): t = i: Max = i
    Next i
    Max = Max + 169
    txtMax = Str(Max)
    For i = 1 To 11
    If c(i) = MaxN And i <> t Then
    c1 = i + 169
    txtMax = txtMax & " " & Str(c1)
    End If
    Next i
    Sum = Sum \ 50
    Print #2, "平均數:" & Sum
    Print #2, "眾數:"; txtMax
    Print #2, "出現次數:" & MaxN
    Close #2
    End Sub

    回覆刪除
  14. Dim a(170 To 180) As Integer
    Dim av As Long
    Public Sub Form_Load()
    Me.Hide
    Open App.Path & "/out.txt" For Output As #2
    For i = 1 To 50
    z = Int(Rnd * 11) + 170
    a(z) = a(z) + 1
    Next i
    av = 0: m = 0: k = 1
    For i = 170 To 180
    If a(i) > m Then m = a(i)
    av = av + i * a(i)
    n = 1:
    Do Until n = a(i) + 1
    Print #2, i,
    If k >= 10 Then
    Print #2,
    k = 0
    End If
    n = n + 1
    k = k + 1
    Loop
    Next i
    Print #2,
    For i = 170 To 180
    If a(i) = m Then Print #2, i, m
    Next i
    Print #2, av / 50
    Close #2
    End
    End Sub

    10分鐘

    回覆刪除
  15. OK,
    (這樣回,會不會太短?)
    熊掌

    回覆刪除
  16. 作者已經移除這則留言。

    回覆刪除
  17. #試試Python版
    #平均數、眾數,先產生50個亂數,170-180之間。
    import random
    #random.randint(a, b)
    #回傳一個整數 N (a <= N <= b)。
    a=[]
    for i in range(50):
    a.append(random.randint(170,180))
    print(a)
    #產生50個亂數完成

    #計算list中,各數出現的次數
    b=[]
    for i in range(170,181):
    b.append(a.count(i))
    print(b)

    #找出b中的最大數
    bmax=max(b)
    print(max(b))

    #再回頭在b中,看誰是出現bmax的,
    #但是,因為有可能有1個以上,
    #所以不好直接用 list.index(obj)

    #再試著將結果寫到檔案去
    f=open('out.txt','w')
    f.write('50個亂數:\n')
    for i in a:
    f.write(str(i)+' ')
    f.write('\n')

    #從列表中找出某個值第一個匹配項的索引位置
    #一個一個來吧。
    for i in range(11):
    if b[i] == bmax:
    print(i+170,'是眾數,出現',bmax,'次')
    f.write('眾數:' + str (i+170) +',出現:' + str(bmax) + '次\n')

    #平均當然是簡單些,還是土法煉鋼,每個加吧
    sum=0
    for i in a:
    sum +=i
    print('平均:',sum / len(a))
    f.write('平均:' + str( sum/len(a)))
    f.close()

    回覆刪除
  18. 但是,貼上Python程式,空白卻沒表現出來,這在Python中,很重要的。(反正只是試試)

    回覆刪除