|
本帖最后由 香川群子 于 2014-9-12 14:29 编辑
对于1个乱序的一维数组来说,要查询第k个大小的值是什么,
可以使用两种工作表函数:
1. Small
例如:=SMALL(A2:A10,4) 查询A2:A10区域中,从小到大升序时,位列第4小的值。
2. Large
例如:=LARGE(A2:B6,3) 查询A2:B6区域中,从大到小降序时,位列第3大的值。
上述工作表函数也可以直接在VBA中使用。
例如:
ar = [a1:c10]
t1 = WorksheetFunction.Small(ar, 3)
t3 = WorksheetFunction.Large(ar, 5)
…………
上述工作表函数使用方便,效率高。(无需对全部数据排序、即可得到结果。)
但是有一个缺点:只能计算数值,不能对文本进行排序比较、输出第k个大小的结果。
…………
因此,我产生了自己写一个更为通用的、不用全部排序就可直接返回第k个大小排序值的自定义函数的想法。
第1步,先写成了用于VBA内存一维数组对象、查询返回第k个大小的值的自定义函数=LargeSmall(ar,k,[z])- Function LargeSmall(ByVal ar, ByVal k&, Optional z& = 0)
- Dim l&, u&
- l = LBound(ar): u = UBound(ar)
- If z Then k = u - l - k + 1 Else k = l + k - 1
- LargeSmall = QuickSort2(ar, l, u, k)
- End Function
- Function QuickSort2(tr, l&, u&, k&)
- Dim i&, j&, r, t
- i = l: j = u: r = tr((l + u) \ 2)
- While i < j
- Do While i < u
- If tr(i) < r Then i = i + 1 Else Exit Do
- Loop
- Do While j > l
- If tr(j) > r Then j = j - 1 Else Exit Do
- Loop
- If i < j Then t = tr(i): tr(i) = tr(j): tr(j) = t: i = i + 1: j = j - 1 Else If i = j Then i = i + 1: j = j - 1
- Wend
- If k < j + 1 Then If j > l Then Call QuickSort2(tr, l, j, k)
- If k > i - 1 Then If i < u Then Call QuickSort2(tr, i, u, k)
- QuickSort2 = tr(k)
- End Function
复制代码 原理是:
利用QuickSort排序算法,但仅仅比较排序到能输出第k个大小的值即可停止。这样就比完成全部排序要快。
1楼自定义函数仅能用于一维数组,4楼自定义函数改为可以兼容二维数组。
|
评分
-
1
查看全部评分
-
|