我有20套两对字符串,每对字符串的长度都可以从1到5个字符。在大多数情况下,它们实际上是1到52之间的整数,或者有时是一个浮点数,在1到53之间有一个小数位(例如52.3将是最大值)。有时,使用大于或小于符号,会将最大字符数增加到5(例如> 26.2)。
将对这组20组进行大量比较(大约25k左右,这意味着一次比较的〜500K,如下图所示)。我的猜测是,最好的存储选项是字符串,而不是每次都测试它以查看它是字符串,整数还是浮点数(但是如果我错了,请更正我)。可以以任何方式将字符串配对(例如,允许成对重复)
我将以20个为例:
- 12 13
- 13 14
让我们使用字母来表示它们A,B,C和D,这样我们就不会忽略它们是字符串的事实并了解它们之间的比较。 A = 12,B = 13,C = 14 ...在此示例中,没有D,但可能有其他D。
- AB
- BC
现在我们看到了,我们可以推断出10种可能的匹配方式,以及3种可能不会匹配的方式...并且根据它们的共享方式,从字典中返回7个值之一,集合或索引,数组等。
- AA AA(共享两个都获得索引值1)
- AA AB(共享1双重获得索引值2)
- AA BA(共享1双重获得索引值2)
- AB AA(共享1st双重获得索引值2)
- AB BB(第二股双倍获得指数值3)
- AB AB(份额2获得索引值4)
- AB AC(一次共享一次获得索引值5)
- AB CA(一次共享一次获得索引值5)
9。 AB BC(第二次共享获得索引值6)
- AB CB(第二次共享获得索引值6)
- AA BC(不共享,索引值为7)
- AB CD(共享不获得索引值7)
- AB CC(不共享,将获得索引值7)
在上面的12,13和13,14的示例中,列表中的数字9是比较结果,我需要获取索引值为6。
撇开我如何获取索引值或这些集合如何出现,我想着重于确定返回哪个索引值的逻辑。我尝试了一个大型嵌套的If-Ifelse,而且运行速度非常慢(进行500k比较时,大约需要7个小时)。我想下一步就是做一个嵌套的select案例,我将在这里显示它:
For i = 0 To 20
Select Case A
Case B
Select Case A
Case C
Select Case A
Case D
'code to get AAAA index value 1
Case Else
'code to get AAAB index value 2
End Select
Case Else
Select Case A
Case D
'code to get AABA index value 2
Case Else
'code to get AABC index value 7
End Select
End Select
Case Else
Select Case A
Case C
Select Case A
Case D
'code to get ABAA index value 2
Case Else
Select Case B
Case D
'code to get ABAB index value 4
Case Else
'code to get ABAC index value 5
End Select
End Select
Case Else
Select Case B
Case C
Select Case B
Case D
'code to get ABBB index value 3
Case Else
'code to get ABBC index value 6
End Select
Case Else
Select Case A
Case D
'code to get ABCA index value 5
Case Else
Select Case B
Case D
'code to get ABCB index value 6
Case Else
'all thats left code to get ABCD and ABCC index value 7
End Select
End Select
End Select
End Select
End Select
Next i
再次...异常缓慢。我已经尝试过通过将字符串分别存储在数组,字典,类对象中并对其进行迭代来尝试优化比较而无济于事的方法。我认为我已将这个问题归结为是造成问题的原因。不要误会我的意思。对于1组20,它的闪电速度很快,但是当我需要做50,000次时,它需要7个小时。
我还没有尝试过但有一点兴趣的是外部vbscript或C ++多线程代码进行比较(我对vbscipt C ++或多线程一无所知,所以目前这是毫无疑问的。那怎么办?关于如何加快比较的任何建议?
答案 0 :(得分:1)
我修改了一个示例代码。它基本上从4个输入参数创建一个代码4位代码字符串,然后在一个静态字典中查找该值分配给该代码的静态字典。虽然尚未测试所有版本。
在测试中,在不到2秒的时间内运行了500.000次迭代。这将取决于您如何读取所有字符串而增加,但是比较本身不是问题。
您将需要对脚本库的引用
Option Explicit
Dim codeTab As Dictionary
Sub test()
Debug.Print getCode("12", "13", "13", "14")
End Sub
Sub initTab()
Set codeTab = New Dictionary
codeTab.Add "AAAA", 1
codeTab.Add "AAAB", 2
codeTab.Add "AABA", 2
codeTab.Add "ABAA", 2
codeTab.Add "ABBB", 3
codeTab.Add "ABAB", 4
codeTab.Add "ABAC", 5
codeTab.Add "ABCA", 5
codeTab.Add "ABBC", 6
codeTab.Add "ABCB", 6
codeTab.Add "AABC", 7
codeTab.Add "ABCD", 7
codeTab.Add "ABCC", 7
End Sub
Function getCode(p1 As String, p2 As String, p3 As String, p4 As String) As Integer
Dim p(), code As String, nextFree As String
' Create an array out of the parameters to enable looping.
p = Array(p1, p2, p3, p4)
code = ""
nextFree = "A"
Dim i As Integer, j As Integer
For i = 0 To 3 ' loop over all 4 values
Dim found As Boolean: found = False
For j = 0 To i - 1 ' compare the value with previous values
If p(i) = p(j) Then ' value already there, add matching letter
found = True
code = code & Mid(code, j + 1, 1)
Exit For
End If
Next j
If Not found Then ' new value, use next free letter
code = code & nextFree
nextFree = Chr(Asc(nextFree) + 1)
End If
Next i
' Debug.Print code
getCode = codeTab(code)
End Function
答案 1 :(得分:0)
我之所以仅发布此内容,是因为我早些时候说过。我向数据库管理员论坛提出了问题,并在提出一些建议后回答了我自己的问题。我很满足于@FunThomas的回答,因为他至少回答了我当时正在寻找的内容,并希望它能对其他人有所帮助。但是,我已经解决了使用三个表,一组派生表和一堆联接进行二进制比较的问题。 5秒内进行67,000次比较。我确定我可以使用更多索引并优化sql和任何前端代码来加快速度。感谢您的所有帮助!
我将其移回一点以编辑帖子。我只是希望那些随后关注的人能看到他们。