Excel精英培训网

 找回密码
 注册
查看: 3734|回复: 14

[习题] 【VBA字典数组201301班】课前热身习题四

[复制链接]
发表于 2013-10-22 14:40 | 显示全部楼层 |阅读模式
本帖最后由 sliang28 于 2013-10-30 09:17 编辑

经过前面三道题测试,本题目对你们来说也不算什么了{:3912:}

没有时间限制,做出来及格.当然时间快的就更优秀{:2312:}

回帖不提交答案的,扣光你的积分和金币,让你从幼儿园小班再开始{:2812:}


注意了:题目中第二大有些歧义,第二大的意思是指相当于large函数取第几大一样.

答案上传了,你们做完核对一下.

热身题之汇总取值.zip

1.48 MB, 下载次数: 606

习题四答案请参照此附件答案.zip

1.48 MB, 下载次数: 294

发表于 2013-10-22 16:28 | 显示全部楼层
本帖最后由 Sellby 于 2013-10-28 16:05 编辑

第二大
  1. Sub sellby()

  2.     Dim arr, tempArr(), brr(1 To 3)

  3.     Dim d As New Dictionary

  4.     Dim i&, iCode$, iDate As Date, t

  5.     t = Timer

  6.     With ThisWorkbook.Sheets(1)

  7.         arr = .Range("a2:c" & Cells(Rows.Count, 1).End(3).Row)

  8.         For i = 2 To UBound(arr)

  9.             iCode = arr(i, 1)

  10.             iDate = arr(i, 2)

  11.             If Not d.Exists(iCode) Then

  12.                 d.Add (iCode), Array(iDate, iDate, 1)
  13.                  '建一个字典,key是第一列Code,item是一个数组(含最大日期,第二大日期,计数)
  14.             Else

  15.                 tempArr = d(iCode)    '将item赋给数组tempArr

  16.                 tempArr(2) = tempArr(2) + 1   ' 计数+1

  17.                 If iDate > tempArr(0) Then    '当日期大于最大日期时

  18.                     tempArr(1) = tempArr(0)   ‘将最大日期赋给第二大日期

  19.                     tempArr(0) = iDate     '将日期赋给最大日期

  20.                 ElseIf iDate > tempArr(1) Then  ’当日期小于最大日期且大于第二大日期时

  21.                     tempArr(1) = iDate   ‘将日期赋给第二大日期

  22.                 ElseIf iDate<tempArr(1) And tempArr(2)=2 Then

  23.                     
  24. tempArr(1) = iDate   ‘将日期赋给第二大日期

  25.                 End If

  26.                 d(iCode) = tempArr     '将新的tempArr赋给字典的item

  27.             End If

  28.         Next i

  29.         brr(1) = arr(1, 1): brr(2) = arr(1, 2): brr(3) = arr(1, 3)

  30.         tempArr = Application.Transpose(d.Items)

  31.         .Range("e2:g" & Rows.Count).Clear

  32.         .Range("e2:g2") = brr

  33.         .Range("e3").Resize(d.Count) = Application.Transpose(d.Keys)

  34.         .Range("f3").Resize(d.Count) = Application.Transpose(Application.Index(tempArr, 2))

  35.         .Range("g3").Resize(d.Count) = Application.Transpose(Application.Index(tempArr, 3))

  36.     End With

  37.     Set d = Nothing

  38.     MsgBox Timer - t

  39. End Sub
复制代码

点评

修改后结果正确 时间为:0.35秒  发表于 2013-10-28 16:31
d.Add (iCode), Array(iDate, iDate, 1) 如果一开始赋值就是最大值的话,那么以后的判断将无法找到第二大,请重新修改代码  发表于 2013-10-28 14:50

评分

参与人数 1 +10 金币 +10 收起 理由
sliang28 + 10 + 10 很给力!

查看全部评分

回复

使用道具 举报

发表于 2013-10-22 17:04 | 显示全部楼层
  1. Sub test()
  2.     Dim d1, d2, d3
  3.     Dim arr, brr, crr, k As Long
  4.     Set d1 = CreateObject("scripting.dictionary")
  5.     Set d2 = CreateObject("scripting.dictionary")
  6.     Set d3 = CreateObject("scripting.dictionary")
  7.     arr = Range("a3:c" & Range("a" & Cells.Rows.Count).End(xlUp).Row)
  8.     For k = 1 To UBound(arr)
  9.         If d1.Count = 0 Then d1(arr(k, 1)) = arr(k, 2) Else If arr(k, 2) > d1(arr(k, 1)) Then d1(arr(k, 1)) = arr(k, 2)
  10.         If d2.Exists(arr(k, 1)) = False Then d2(arr(k, 1)) = 9E+307 Else If Abs(d1(arr(k, 1)) - arr(k, 2)) < d2(arr(k, 1)) And d1(arr(k, 1)) <> arr(k, 2) Then d2(arr(k, 1)) = Abs(d1(arr(k, 1)) - arr(k, 2))
  11.         If d3.Count = 0 Then d3(arr(k, 1)) = 1 Else d3(arr(k, 1)) = d3(arr(k, 1)) + 1
  12.     Next k
  13.     Range("m3").Resize(d1.Count, 1) = Application.WorksheetFunction.Transpose(d1.keys)
  14.     brr = d1.items
  15.     crr = d2.items
  16.     For k = 1 To d1.Count
  17.         Range("n2").Offset(k, 0) = brr(k - 1) - crr(k - 1)
  18.     Next k
  19.     Range("o3").Resize(d1.Count, 1) = Application.WorksheetFunction.Transpose(d3.items)
  20. End Sub
复制代码

点评

11楼修改过的代码有误,请重新修改  发表于 2013-10-28 15:34
回复

使用道具 举报

发表于 2013-10-22 18:42 | 显示全部楼层
本帖最后由 xdragon 于 2013-10-23 23:41 编辑
  1. Sub xdragon()
  2. Dim arr, dic As Object, dic1 As Object, dic2 As Object, i As Long, r As Long, t
  3. t = Timer
  4. With Sheets("sheet1")
  5.   r = .Cells(Rows.Count, 1).End(3).Row
  6.   arr = .Range("A3:C" & r)
  7. ReDim arr2(1 To UBound(arr))
  8. Set dic = CreateObject("scripting.dictionary")
  9. Set dic1 = CreateObject("scripting.dictionary")
  10. Set dic2 = CreateObject("scripting.dictionary")
  11. For i = 1 To UBound(arr)
  12.   If Not dic.exists(arr(i, 1)) Or Not dic2.exists(arr(i, 1)) Then
  13.     dic(arr(i, 1)) = dic(arr(i, 1)) + arr(i, 3)
  14.     If Not dic1.exists(arr(i, 1)) Then
  15.       dic1(arr(i, 1)) = arr(i, 2)
  16.     Else
  17.       If arr(i, 2) < dic1(arr(i, 1)) Then
  18.         dic2(arr(i, 1)) = dic1(arr(i, 1))
  19.         dic1(arr(i, 1)) = arr(i, 2)
  20.       Else
  21.         dic2(arr(i, 1)) = arr(i, 2)
  22.       End If
  23.     End If
  24.   Else
  25.     dic(arr(i, 1)) = dic(arr(i, 1)) + arr(i, 3)
  26.     If arr(i, 2) >= dic2(arr(i, 1)) Then
  27.       dic1(arr(i, 1)) = dic2(arr(i, 1))
  28.       dic2(arr(i, 1)) = arr(i, 2)
  29.     Else
  30.       If arr(i, 2) >= dic1(arr(i, 1)) Then dic1(arr(i, 1)) = arr(i, 2)
  31.     End If
  32.   End If
  33. Next
  34. .Range("E3:E" & dic.Count + 2) = Application.Transpose(dic.keys)
  35. .Range("F3:F" & dic.Count + 2) = Application.Transpose(dic1.items)
  36. .Range("G3:G" & dic.Count + 2) = Application.Transpose(dic.items)
  37. End With
  38. MsgBox Timer - t
  39. End Sub
复制代码

点评

0.58秒  发表于 2013-10-28 14:51

评分

参与人数 1 +10 金币 +10 收起 理由
sliang28 + 10 + 10 赞一个!

查看全部评分

回复

使用道具 举报

发表于 2013-10-22 18:44 | 显示全部楼层
  1. '前期绑定字典
  2. Sub hoogle()
  3. Dim t As Double
  4. t = Timer
  5. Dim arrData, i As Long, j As Long, arrRes(1 To 1000, 1 To 4), Temp As Integer
  6. Dim d As New dictionary
  7. With Sheets("Sheet1")
  8.   arrData = .Range("a3", .Cells(Rows.Count, 3).End(3))
  9. For i = 1 To UBound(arrData)
  10.   If Not d.exists(arrData(i, 1)) Then
  11.     j = j + 1
  12.     d(arrData(i, 1)) = j
  13.     arrRes(j, 1) = arrData(i, 1)
  14.     arrRes(j, 3) = 1
  15.     arrRes(j, 4) = arrData(i, 2)
  16.     arrRes(j, 2) = arrData(i, 2)
  17.   Else
  18.     Temp = d(arrData(i, 1))
  19.     arrRes(Temp, 3) = arrRes(Temp, 3) + 1
  20.     If arrData(i, 2) > arrRes(Temp, 2) Then
  21.       If arrData(i, 2) > arrRes(Temp, 4) Then
  22.         arrRes(Temp, 2) = arrRes(Temp, 4)
  23.         arrRes(Temp, 4) = arrData(i, 2)
  24.       Else
  25.         arrRes(Temp, 2) = arrData(i, 2)
  26.       End If
  27.     End If
  28.   End If
  29. Next
  30. .Range("j3").Resize(10000, 3).ClearContents
  31. .Range("j3").Resize(10000, 3) = arrRes
  32. End With
  33. Debug.Print Timer - t
  34. End Sub
复制代码

点评

arrRes数组装入时如果为最大值,后面的比较无法得出第二大,请重新修改代码  发表于 2013-10-28 15:07
回复

使用道具 举报

发表于 2013-10-23 00:13 | 显示全部楼层
本帖最后由 w2001pf 于 2013-10-28 17:11 编辑

Sub 汇总()
    t = Timer
    Application.ScreenUpdating = False
    Dim d As New Dictionary
    Dim d1 As New Dictionary
    Dim d2 As New Dictionary
    Dim d3 As New Dictionary
    With Sheets("Sheet1")
        rowend = .Range("A" & Rows.Count).End(xlUp).Row
        arr = .Range("A3:C" & rowend)
    End With
    For i = 1 To UBound(arr)
        d(arr(i, 1)) = d(arr(i, 1)) + 1
        If Not d1.Exists(arr(i, 1)) Then
            d1(arr(i, 1)) = arr(i, 2)
        Else
            If d1(arr(i, 1)) < arr(i, 2) Then d1(arr(i, 1)) = arr(i, 2)
        End If
    Next i
    For i = 1 To UBound(arr)
        If Not d2.Exists(arr(i, 1)) Then
            d2(arr(i, 1)) = 1
        Else
            If d1(arr(i, 1)) <> arr(i, 2) Then d2(arr(i, 1)) = d2(arr(i, 1)) + 1
        End If
    Next i
    For i = 1 To UBound(arr)
        If d2(arr(i, 1)) = 1 Then
            arr(i, 2) = arr(i, 2)
        Else
            If arr(i, 2) = d1(arr(i, 1)) Then arr(i, 2) = 0
        End If
    Next i
    For i = 1 To UBound(arr)
        If d3(arr(i, 1)) < arr(i, 2) Then d3(arr(i, 1)) = arr(i, 2)
    Next i
    ReDim arr1(1 To d.Count, 1 To 3)
     With Sheets("Sheet1")
        .Range("J3").Resize(d.Count, 3) = ""
        .Range("J3").Resize(d.Count) = Application.Transpose(d.Keys)
        .Range("K3").Resize(d.Count) = Application.Transpose(d3.Items)
         .Range("L3").Resize(d.Count) = Application.Transpose(d.Items)
    End With

    MsgBox Timer - t
    Application.ScreenUpdating = True
End Sub

点评

结果有误,请重新修改!  发表于 2013-10-28 15:09
回复

使用道具 举报

发表于 2013-10-23 10:39 | 显示全部楼层
本帖最后由 hrpotter 于 2013-10-23 14:17 编辑
  1. Sub test()
  2.     Dim arr, brr(1 To 10000, 1 To 2), temp(1 To 10000), d, t As Single
  3.     Dim i As Long, j As Long, k As Long
  4.     t = Timer
  5.     Set d = CreateObject("scripting.dictionary")
  6.     With Sheet1
  7.         arr = .Range("a1").CurrentRegion
  8.         For i = 3 To UBound(arr)
  9.             If d.exists(arr(i, 1)) Then
  10.                 k = d(arr(i, 1))
  11.                 brr(k, 2) = brr(k, 2) + 1
  12.                 If arr(i, 2) <= temp(k) And arr(i, 2) > brr(k, 1) Then
  13.                     brr(k, 1) = arr(i, 2)
  14.                 ElseIf arr(i, 2) > temp(k) Then
  15.                     brr(k, 1) = temp(k)
  16.                     temp(k) = arr(i, 2)
  17.                 End If
  18.             Else
  19.                 j = j + 1
  20.                 d(arr(i, 1)) = j
  21.                 brr(j, 2) = 1
  22.                 temp(j) = arr(i, 2)
  23.             End If
  24.         Next
  25.         For i = 1 To j
  26.             If brr(i, 1) = "" Then
  27.                 brr(i, 1) = temp(i)
  28.             End If
  29.         Next
  30.         .Range("j3").Resize(j, 3).ClearContents
  31.         .Range("j3").Resize(j, 1) = Application.Transpose(d.keys)
  32.         .Range("k3").Resize(j, 2) = brr
  33.     End With
  34.     MsgBox Timer - t
  35. End Sub
复制代码

点评

0.29秒  发表于 2013-10-28 15:10

评分

参与人数 1 +10 金币 +20 收起 理由
sliang28 + 10 + 20 神马都是浮云

查看全部评分

回复

使用道具 举报

发表于 2013-10-23 12:09 | 显示全部楼层
本帖最后由 fffox 于 2013-10-23 20:25 编辑

自己的破电脑上运行时间是0.8秒
改了,这结果应该可以了吧
  1. Sub hz()            '采用校长的下棋法
  2.     Dim t, d
  3.     Dim arr, brr(1 To 1000, 1 To 3), crr(1 To 1000) As Date   '定义arr为数据源数组,brr为结果数组,crr为最大值数组
  4.     Dim i As Long, k As Long, rs As Long
  5.     t = Timer
  6.     Set d = CreateObject("scripting.dictionary")
  7.     Application.DisplayAlerts = False
  8.     With Sheets("sheet1")
  9.         arr = .Range("a3:c" & .Cells(Rows.Count, 3).End(xlUp).Row)
  10.         For i = 1 To UBound(arr)
  11.             If d.exists(arr(i, 1)) Then
  12.                 rs = d(arr(i, 1))                       '结果数组中的行数
  13.                 brr(rs, 3) = brr(rs, 3) + arr(i, 3)     'Qty.值增加
  14.                 If brr(rs, 3) = 2 Then
  15.                     If crr(rs) < arr(i, 2) Then
  16.                         crr(rs) = arr(i, 2)
  17.                     Else
  18.                         brr(rs, 2) = arr(i, 2)
  19.                     End If
  20.                 ElseIf crr(rs) < arr(i, 2) Then
  21.                     brr(rs, 2) = crr(rs)
  22.                     crr(rs) = arr(i, 2)
  23.                 ElseIf crr(rs) >= arr(i, 2) And brr(rs, 2) <= arr(i, 2) Then
  24.                     brr(rs, 2) = arr(i, 2)
  25.                 End If
  26.             Else                                        '对应Code在结果数组中不存在时
  27.                 k = k + 1
  28.                 d(arr(i, 1)) = k
  29.                 brr(k, 1) = arr(i, 1): brr(k, 2) = arr(i, 2)
  30.                 brr(k, 3) = arr(i, 3): crr(k) = arr(i, 2)
  31.             End If
  32.         Next
  33.         .Range("j3").Resize(k, 3).ClearContents         '清空目标区域
  34.         .Range("j3").Resize(k, 3) = brr                 '写入目标区域
  35.     End With
  36.     Application.ScreenUpdating = True
  37.     MsgBox Timer - t
  38. End Sub
复制代码

点评

0.29秒  发表于 2013-10-28 15:11

评分

参与人数 1 +10 金币 +20 收起 理由
sliang28 + 10 + 20 神马都是浮云

查看全部评分

回复

使用道具 举报

发表于 2013-10-23 12:47 | 显示全部楼层
本帖最后由 CheryBTL 于 2013-10-25 15:04 编辑

时间还早,来网吧改的,请学委确认是否正确:
  1. Sub CheryBTL()
  2.     Dim i As Long, j As Integer, t As Single
  3.     Dim ar, re1(1 To 1000, 1 To 1) As Integer, re2(1 To 1000, 1 To 2), temp
  4.     Dim d As Object
  5.     t = Timer
  6.     ar = Sheets(1).Range("A1").CurrentRegion
  7.     Set d = CreateObject("Scripting.Dictionary")
  8.     For i = 3 To UBound(ar)
  9.         If Not d.exists(ar(i, 1)) Then
  10.             m = m + 1
  11.             d(ar(i, 1)) = m
  12.             re1(m, 1) = 1
  13.             re2(m, 1) = ar(i, 2)
  14.         Else
  15.             n = d(ar(i, 1))
  16.             re1(n, 1) = re1(n, 1) + 1
  17.             If ar(i, 2) >= re2(n, 1) Then
  18.                 temp = re2(n, 1)
  19.                 re2(n, 1) = ar(i, 2)
  20.                 re2(n, 2) = temp
  21.             ElseIf ar(i, 2) >= re2(n, 2) Then
  22.                 re2(n, 2) = ar(i, 2)
  23.             End If
  24.         End If
  25.     Next i
  26.     For i = 1 To d.Count
  27.         If re2(i, 2) = "" Then re2(i, 2) = re2(i, 1)
  28.     Next i
  29.     With Sheets(1)
  30.         .Range("J3").Resize(d.Count, 3).ClearContents
  31.         .Range("J3").Resize(d.Count) = Application.Transpose(d.keys)
  32.         .Range("k3").Resize(d.Count) = Application.Index(re2, 0, 2)
  33.         .Range("L3").Resize(d.Count) = re1
  34.     End With
  35.     MsgBox Timer - t
  36. End Sub
复制代码

点评

0.29秒  发表于 2013-10-28 15:14

评分

参与人数 1 +10 金币 +20 收起 理由
sliang28 + 10 + 20 神马都是浮云

查看全部评分

回复

使用道具 举报

发表于 2013-10-24 18:22 | 显示全部楼层
本帖最后由 缔造者 于 2013-10-27 15:58 编辑

给出的效果结果中个别第二大值貌似有误,请核查!
提取第二大值没想出好法,经向“山菊花”版主请教,套用了他的程序,结果第二大值还是有误,暂提交。
经“yangyangzhifeng”高手的再次修改,基本正确。
“yangyangzhifeng”的代码:
  1. Sub test()
  2.     Dim d As Object, ds As Object
  3.     Dim i&, ar, t, br(), r
  4.     Set d = CreateObject("scripting.dictionary")
  5.     Set ds = CreateObject("scripting.dictionary")
  6.     ar = Sheet1.Range("a1").CurrentRegion
  7.     ReDim br(1 To UBound(ar), 1 To 3)
  8.     For i = 3 To UBound(ar)
  9.         r = d(Trim(ar(i, 1)))
  10.         If r = "" Then
  11.             r = d.Count: d(Trim(ar(i, 1))) = r
  12.             br(r, 1) = ar(i, 1)
  13.             br(r, 2) = ar(i, 2)
  14.             ds(Trim(ar(i, 1))) = ar(i, 3)
  15.         Else
  16.             ds(Trim(ar(i, 1))) = ds(Trim(ar(i, 1))) + ar(i, 3)
  17.             If br(r, 3) = "" Then
  18.                 br(r, 3) = ar(i, 2)
  19.                 If br(r, 2) > br(r, 3) Then
  20.                     t = br(r, 2): br(r, 2) = br(r, 3): br(r, 3) = t
  21.                 End If
  22.             Else
  23.                 If ar(i, 2) > br(r, 3) Then
  24.                     br(r, 2) = br(r, 3): br(r, 3) = ar(i, 2)
  25.                 ElseIf ar(i, 2) > br(r, 2) Then
  26.                     br(r, 2) = ar(i, 2)
  27.                 End If
  28.             End If
  29.         End If
  30.     Next
  31.     Range("n2").Resize(UBound(ar), 3).ClearContents
  32.     Range("n2:p2") = Array("Code", "Date", "Qty.")
  33.     [n3].Resize(d.Count, 2) = br
  34.     [p3].Resize(ds.Count, 1) = Application.Transpose(ds.items)
  35.     Set d = Nothing
  36.     Set ds = Nothing
  37. End Sub

复制代码
“山菊花”版主的代码(修改后的正确代码):
  1. Sub tiqu()
  2. Dim ds As Object, d As Object
  3. Dim nRow&, i&, n&, m&, Arr(), Brr()
  4. Set ds = CreateObject("scripting.dictionary") '定义字典
  5. Set d = CreateObject("scripting.dictionary")
  6. nRow = Range("a1").CurrentRegion.Rows.Count
  7. Arr = Range("a3:c" & nRow).Value
  8. ReDim Brr(1 To nRow, 1 To 3)
  9. For i = 1 To nRow - 2
  10. n = ds(Arr(i, 1))
  11. If n = 0 Then
  12. m = m + 1
  13. n = m
  14. ds(Arr(i, 1)) = m
  15. d(Arr(i, 1)) = Arr(i, 3)
  16. Brr(m, 1) = Arr(i, 1)
  17. Else
  18. d(Arr(i, 1)) = d(Arr(i, 1)) + Arr(i, 3)
  19. End If
  20. If Arr(i, 2) >= Brr(n, 3) Then
  21. Brr(n, 2) = Brr(n, 3)
  22. Brr(n, 3) = Arr(i, 2)
  23. ElseIf Arr(i, 2) > Brr(n, 2) Then
  24. Brr(n, 2) = Arr(i, 2)
  25. End If
  26. Next
  27. For i = 1 To m
  28. If Brr(i, 2) = "" Then Brr(i, 2) = Brr(i, 3)
  29. Next
  30. Range("q2:s2") = Array("Code", "Date", "Qty.")
  31. Range("q3:r" & nRow).Value = Brr
  32. Range("s3").Resize(d.Count, 1).Value = Application.Transpose(d.items)
  33. Set d = Nothing
  34. Set ds = Nothing
  35. End Sub

复制代码

点评

0.43秒  发表于 2013-10-28 15:27

评分

参与人数 1 +10 金币 +10 收起 理由
sliang28 + 10 + 10 赞一个!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-5-4 02:19 , Processed in 0.282472 second(s), 10 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表