0

您能否协助/请求代码片段以有效排序。找不到 vbscript 的基数排序 - 二维数组/能够很好地实现。

我的数组的示例结构是:

resultarray(0,1) = "Name1"
resultarray(1,1) = "Score1"
resultarray(2,1) = "Category1"
resultarray(3,1) = "OtherDetail1"
resultarray(4,1) = "OtherDetail1"
resultarray(5,1) = "OtherDetail1"

resultarray(0,2) = "Name2"
resultarray(1,2) = "Score2"
resultarray(2,2) = "Category2"
resultarray(3,2) = "OtherDetail2"
resultarray(4,2) = "OtherDetail2"
resultarray(5,2) = "OtherDetail2"

resultarray(0,3) = "Name3"
resultarray(1,3) = "Score3"
resultarray(2,3) = "Category3"
resultarray(3,3) = "OtherDetail3"
resultarray(4,3) = "OtherDetail3"
resultarray(5,3) = "OtherDetail3"

数组必须根据第二列进行排序,即分数。行数大约为几百万。分数将始终为正整数(在不久的将来需要两位小数)。速度非常重要,因为这必须针对 30 到 40 个不同组的几万到几百万个数字进行。

目前使用Quicksort完全来自:

http://www.4guysfromrolla.com/webtech/012799-3.shtml

我在我的实现中交换了行 <-> 列,然后这工作正常。但是慢。是否值得从现有的 QuickSort 更改排序技术。

我打算稍后使用二进制搜索来根据分数匹配搜索大约 2000 个元素。

谢谢

4

3 回答 3

0

To illustrate why

  1. you shouldn't duplicate the data from the original array in the ArrayList, but use/store an index
  2. a SortedList is appropriate for a problem of grouping (not sorting)

Proof of concept script:

  Dim nRecs : nRecs = 100
  ReDim aOrg(1, nRecs)
  Dim i
  For i = 1 To nRecs ' aOrg[0] intentinally wasted
      aOrg(0, i) = "Item " &  i
      aOrg(1, i) = IRandR(5, 16)
  Next
  Dim slX : Set slX = CreateObject("System.Collections.SortedList")
  For i = 1 To nRecs
      If Not slX.Contains(aOrg(1, i)) Then Set slX(aOrg(1, i)) = CreateObject("System.Collections.ArrayList")
      slX(aOrg(1, i)).Add i
  Next
  For i = 0 To slX.Count - 1
      WScript.Echo "---- #", i, "score:", slX.GetKey(i)
      WScript.Echo vbTab, Join(slX.GetByIndex(i).ToArray())
      WScript.Echo vbTab, Join(GetCargo(aOrg, slX.GetByIndex(i)))
  Next

Function GetCargo(aO, aI)
  ReDim aTmp(aI.Count - 1)
  Dim i
  For i = 0 To UBound(aTmp)
      aTmp(i) = aO(0, aI(i))
  Next
  GetCargo = aTmp
End Function

output:

---- # 0 score: 5
         7 11 18 23 44 50 69 85 96 99
         Item 7 Item 11 Item 18 Item 23 Item 44 Item 50 Item 69 Item 85 Item 96 Item 99
---- # 1 score: 6
         41 46 47 58 59 80
         Item 41 Item 46 Item 47 Item 58 Item 59 Item 80
---- # 2 score: 7
         29 36 39 66 67 72 95 97
         Item 29 Item 36 Item 39 Item 66 Item 67 Item 72 Item 95 Item 97
---- # 3 score: 8
         4 5 26 30 49 51 53 57 64 75 93
         Item 4 Item 5 Item 26 Item 30 Item 49 Item 51 Item 53 Item 57 Item 64 Item 75 Item 93
---- # 4 score: 9
         12 15 20 52 56 61 62 74 79 88 94 100
         Item 12 Item 15 Item 20 Item 52 Item 56 Item 61 Item 62 Item 74 Item 79 Item 88 Item 94 Item 100
---- # 5 score: 10
         2 21 25 40 70 86 90 91 92
         Item 2 Item 21 Item 25 Item 40 Item 70 Item 86 Item 90 Item 91 Item 92
---- # 6 score: 11
         3 24 27 33 45 65 68 77 78 81
         Item 3 Item 24 Item 27 Item 33 Item 45 Item 65 Item 68 Item 77 Item 78 Item 81
---- # 7 score: 12
         1 10 28 37 43 60 63 82 89
         Item 1 Item 10 Item 28 Item 37 Item 43 Item 60 Item 63 Item 82 Item 89
---- # 8 score: 13
         6 8 9 14 22 48 73
         Item 6 Item 8 Item 9 Item 14 Item 22 Item 48 Item 73
---- # 9 score: 14
         13 17 31 32 71 84
         Item 13 Item 17 Item 31 Item 32 Item 71 Item 84
---- # 10 score: 15
         16 19 34 35 38 42 54 55 76 83 87 98
         Item 16 Item 19 Item 34 Item 35 Item 38 Item 42 Item 54 Item 55 Item 76 Item 83 Item 87 Item 98
于 2013-03-11T20:35:17.503 回答
0

像这样的东西怎么样(使用最大分数作为 sortedarray 的上维):

Dim sortedarray(5, MAXIMUM_SCORE_GOES_HERE)
for i=LBound(resultarray) to UBound(resultarray)
    idxTarget = resultarray(1,i);
    sortedarray(0,idxTarget) = resultarray(0,i)
    sortedarray(1,idxTarget) = resultarray(1,i)
    sortedarray(2,idxTarget) = resultarray(2,i)
    sortedarray(3,idxTarget) = resultarray(3,i)
    sortedarray(4,idxTarget) = resultarray(4,i)
    sortedarray(5,idxTarget) = resultarray(5,i)
Next

这是基数排序,没有基数部分。没有比这更快的了。我像你一样展开了“内循环”,但如果有一个内循环,它可能会更快:而不是索引第一个维度,尝试循环遍历它,它实际上可能更快。此外,您可能想尝试 For Each...Next 而不是上面编写的 for 循环:有时 For Each 更快。但就排序算法而言,更快是不可能的。

于 2013-03-09T07:54:42.680 回答
0

我不知道您在更改和弯曲数据方面有多灵活,但您可以使用 ArrayList 并对其执行 Sort 方法。这是一个概念证明:

option explicit
' Create an arraylist to add items to
Dim i, score, t
dim list : Set list = CreateObject("System.Collections.ArrayList")

for i = 0 to 1000000
        ' Make an arbitrairy score between 0 and 100
        score = cint(rnd*100)
        ' pad with zero's to make the sort work correctly
        score = string(3 - len(score), "0") & score
        ' Add it to the arraylist
        list.add join(array(score, "name", "category", "details1", "details2", "details3"), vbTab)
Next

' Sort the list
t = timer()
list.sort

' Show the list
wscript.echo "duration: " & timer() - t
wscript.echo join(list.toArray(), vbNewLine)

这将返回 2.6 秒的持续时间来对我的机器(Intel i5)上的 1.000.000 个项目进行排序。

如前所述,您不能直接在数据格式上使用它,但如果性能是一项重要要求,则可能值得更改您的数据模型。

于 2013-03-11T15:51:40.893 回答