Двоичное сравнение двух пар строк с использованием Select Case в VBA - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть 20 наборов из двух пар строк, каждая из которых может содержать от 1 до 5 символов.Большую часть времени они на самом деле являются целыми числами от 1 до 52 или иногда числом с плавающей запятой с одним десятичным знаком от 1 до 53 (например, 52,3 будет максимальным значением).В некоторых случаях используется символ больше или меньше и увеличивает максимальное количество символов до 5 (например,> 26,2).

Эти группы из 20 наборов будут сравниваться большое количество раз (порядка 25 тыс. Или около того, что означает ~ 500 тыс. Единичных сравнений, подобных приведенному ниже).Я предполагаю, что лучшим вариантом хранения будет строка, а не проверять ее каждый раз, чтобы увидеть, является ли она строкой, целым числом или с плавающей запятой (но если я ошибаюсь, исправьте меня)Строки могут быть спарены любым способом (например, в паре допускается дубликат)

Я покажу один набор из 20 в качестве примера:

  1. 12 13
  2. 13 14

Позволяет использовать буквы для их представления A, B, C и D, поэтому мы не упускаем из виду тот факт, что они являются строками, и посмотрим, какони сравнивают.A = 12, B = 13 и C = 14 ... в этом примере нет D, но могут быть и другие.

  1. AB
  2. BC

Теперь, когда мы видим это, мы можем экстраполировать до 10 возможных способов их сопоставления и до 3 возможных способов, которыми они не будут ... и в зависимости от того, как они делятся, один из7 значений возвращаются из словаря, коллекции или индекса, массива или чего-либо подобного.

  1. AA AA (совместно используйте оба, чтобы получить значение индекса 1)
  2. AAAB (доля 1, дважды получим значение индекса 2)
  3. AA BA (доля 1, дважды получим значение индекса 2)
  4. AB AA (доля 1, дважды получим значение индекса 2)
  5. AB BB (доля 2 вдвойне получает значение индекса 3)
  6. AB AB (доля 2 получает значение индекса 4)
  7. AB AC (доля 1 раз получает значение индекса 5)
  8. AB CA (доля 1 раз получить значение индекса 5)

9.AB BC (доля 2 раз получить значение индекса 6)

AB CB (поделиться 2-й раз получить значение индекса 6) AA BC (поделиться нет получить значение индекса 7) AB CD (поделиться нет получить значение индекса 7) AB CC (share none, получить значение индекса 7)

В приведенном выше примере 12,13 и 13,14 число девять в списке будет сравнительным результатом, и я бымне нужно получить значение индекса 6.

Если не учитывать, как я получаю значение индекса или как эти наборы подходят, я хочу сосредоточиться на логике, чтобы решить, какое значение индекса вернуть.Я попробовал большой вложенный If - Ifelse, и он был монументально медленным (порядка 7 часов для сравнения 500k).Я подумал, что следующим шагом будет создание вложенного выбора, который я покажу здесь:

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 он быстро осветляется, но когда мне нужно сделать это 50000 раз, это займет 7 часов.

То, что я еще не пробовал, но слегка заинтересовал меня, это внешний многопоточный код vbscript или C ++ для сравнения (я ничего не знаю о vbscipt C ++ или многопоточности, так что на данный момент это не таквопрос. Так как насчет этого? Любые предложения о том, как я могу ускорить сравнение?

Ответы [ 2 ]

0 голосов
/ 17 марта 2019

Я только публикую это, потому что я сказал ранее, что я буду.Я задал свой вопрос на форуме администраторов базы данных и после некоторых предложений закончил тем, что ответил на мой собственный вопрос.Я рад оставить ответ @ FunThomas, потому что он ответил, по крайней мере, на то, что я искал в то время, и, надеюсь, это поможет другим.Однако я решил выполнить это двоичное сравнение, используя три таблицы, набор производных таблиц и несколько объединений.67 000 сравнений за 5 секунд.Я уверен, что я могу ускорить это с помощью большего количества индексов и оптимизации SQL и любого внешнего кода.Спасибо за вашу помощь!

https://dba.stackexchange.com/questions/231866/comparing-two-pairs-of-columns-between-two-tables-and-returning-the-column-from/232370#232370.

Я верну его назад, чтобы немного отредактировать сообщение.Я просто хотел, чтобы те, кто следовал, обратили внимание на случай, если они захотят взглянуть.

0 голосов
/ 12 февраля 2019

Я возился с примером кода.Он в основном создает 4-значную кодовую строку кода из 4 входных параметров, а затем ищет в статическом словаре значение, присвоенное коду.Тем не менее, не проверял все варианты.

В тесте 500 000 итераций выполняются менее чем за 2 секунды.Это будет увеличиваться в зависимости от того, как вы читаете все свои строки, но само сравнение не является проблемой.

Вам понадобится ссылка на библиотеку сценариев

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...