我需要在vb6中的单个数组上运行“mode”(最常出现的值)。在大型阵列上有快速的方法吗?
答案 0 :(得分:2)
在网上看看VB6的排序算法的一个不错的实现(我不敢相信它没有内置的!),对数组进行排序,然后通过它来计算出现次数(这将是直截了当,因为你在阵列中的所有相同的项目一起) - 跟踪你经过的最频繁发生的项目,你已经完成了。这应该是O(n ln(n)) - 也就是说,足够快 - 如果你使用了一个不错的排序算法(quicksort或类似的)。
答案 1 :(得分:2)
您可以使用哈希表。散列数组的所有元素(即O(n))。您需要一个后端数据结构来保存每个哈希箱包含的唯一值和出现次数(某种类似于C ++ std :: map的关联内存)。只要你可以保证在任何给定的bin中只有一个常数,m个冲突数(对于不同的哈希输入值),这是O(m log m),但由于m是常数,这是真的是O(1)。这种假设可能不合理,但关键是要为您的输入值获得足够好的传播。
要拉出模式,请检查哈希表中的所有元素,这些元素将是原始输入数组中出现的值及其出现次数。找到具有最大出现次数的值(再次为O(n))。如果您能找到合适的散列函数,则总复杂度为O(n)。如果散列函数没有为您提供良好的碰撞性能,最坏情况下的性能将为O(n log n)。
另一方面,.Net提供了一个可以使这更容易的大型运行时库。如果可行,您可能需要考虑使用新版本的VB。
答案 2 :(得分:2)
包含对Microsoft Scripting Runtime的引用,并使用Dictionary对象保持频率计数,然后查找索引最高频率,相应的键是模式。这不是最快捷/最优雅的解决方案,但我只是需要一些有效的东西。
Function fnModeSingle(ByRef pValues() As Single) As Single
Dim dict As Dictionary
Set dict = New Dictionary
dict.CompareMode = BinaryCompare
Dim i As Long
Dim pCurVal As Single
For i = 0 To uBound(pValues)
'limit the values that have to be analyzed to desired precision'
pCurVal = Round(pValues(i), 2)
If (pCurVal > 0) Then
'this will create a dictionary entry if it doesn't exist
dict.Item(pCurVal) = dict.Item(pCurVal) + 1
End If
Next
'find index of first largest frequency'
Dim KeyArray, itemArray
KeyArray = dict.Keys
itemArray = dict.Items
pCount = 0
Dim pModeIdx As Integer
'find index of mode'
For i = 0 To UBound(itemArray)
If (itemArray(i) > pCount) Then
pCount = itemArray(i)
pModeIdx = i
End If
Next
'get value corresponding to selected mode index'
fnModeSingle = KeyArray(pModeIdx)
Set dict = Nothing
End Function