代码之家  ›  专栏  ›  技术社区  ›  S31

字符串与列-百分比匹配

  •  0
  • S31  · 技术社区  · 7 年前

    在比较字符串和列时,尝试找出一种计算最小匹配百分比的方法。

    例子:

    Column A        Column B
    Key             Keylime
    Key Chain       Status
                    Serious
                    Extreme
                    Key
    

    在哪里?

    Column A        Column B     Column C                 Column D
    Key             Temp         100%                     Key
    Key Chain       Status       66.7%                    Key Ch
    Ten             Key Ch       100%                     Tenure
                    Extreme       
                    Key
                    Tenure 
    

    在此基础上展开:

    • A列是具有单独匹配的字符串的列
    • B列为参考列
    • C列提供了与B列中的任何字符串匹配的最大百分比。
    • D列提供B列中与最高匹配百分比关联的单词

    在C列上展开-查看 Key Chain -与B列中的任何单词最匹配的是for Key Ch 其中9个字符中的6个(包括空格) 钥匙链 匹配以给出(6/9)=66.7%的匹配百分比

    • 这就是说,这不是一个交易破坏者,但它是一个突出的东西。当你看不到像这样的例子时,上面的逻辑就失败了 Ten 发生。在哪里? 3个字符中有3个与之匹配 Tenure 给它一个膨胀的100%匹配,我仍然想不出一个方法来纠正。
    1 回复  |  直到 7 年前
        1
  •  1
  •   iamanigeeit    7 年前

    这应该是可行的(我还没有测试过,目前在Linux上)。呼叫 getStrMatch 对于每个字符串。

    Type StrMatch
        Percent As Double
        Word As String
    End Type
    
    Function getStrMatch(s As String, RefRange As Range) As StrMatch
        Dim i As Long, ref_str As String
        Dim BestMatch As StrMatch: BestMatch.Percent = -1
        Dim match_pc As Double
        With RefRange
            For i = 1 to .Cells.Count
                ref_str = .Cells(i).Value2
                match_pc = getMatchPc(s, ref_str)
                If match_pc > BestMatch.Percent Then
                    BestMatch.Percent = match_pc
                    BestMatch.Word = ref_str
                End If
            Next i
        End With
        getStrMatch = BestMatch
    End Function
    
    Function getMatchPc(s As String, ref_str As String) As Double
        Dim s_len As Long: s_len = Len(s)
        Dim ref_len As Long: ref_len = Len(ref_str) 
        Dim longer_len as Long
        If s_len > ref_len Then longer_len = s_len Else longer_len = ref_len
        Dim m As Long: m = 1
        While m <= longer_len
            If Mid(s, m, 1) <> Mid(ref_str, m, 1) Then Exit While
            m = m + 1
        Wend
        getMatchPc = (m - 1.0) / longer_len
    End Function
    

    请注意,您必须将它放入模块中,否则将声明 Private Type Private Function .

    另外,如果您匹配了很多字符串,那么您可能应该创建一个trie,因为这只是简单的字符串比较,并且每个getstrmatch的成本为o(mn),其中m是 RefRange n是平均值 ref_str 长度。