【问题标题】:VB.NET - large generic list filtering against another listVB.NET - 针对另一个列表过滤大型通用列表
【发布时间】:2011-10-29 12:15:54
【问题描述】:

我有两个字符串类型的通用列表,第一个包含大约 1,000,000 个术语,第二个包含大约 100,000 个关键字。第一个列表中的术语可能包含也可能不包含第二个列表中的关键字。我需要从第二个列表中分离出第一个列表中不包含任何关键字的术语。 目前我正在这样做(VB.NET with framework 3.5):

For Each keyword In keywordList
    termList.RemoveAll(AddressOf ContainsKeyword)
Next

Private Shared Function ContainsKeyword(ByVal X As String) As Integer
    If X.IndexOf(keyword) >= 0 Then
        Return True
    Else
        Return False
    End If
End Function

不用说,这需要很长时间。最快的方法是什么?也许使用字典?任何提示都会有所帮助

【问题讨论】:

  • 一方面,如果你只是检查一个字符串是否包含某个子字符串,那么使用String.Contains方法而不是String.IndexOf
  • 我刚刚检查了 Dictionary 类,虽然我可以轻松地从每个术语创建一个键/值对,但问题是我必须有重复键,这不好

标签: list generics filtering


【解决方案1】:

关键字的直接字典在这里不起作用,因为您正在进行包含检查,而不仅仅是直接相等检查。您可能采取的一种方法是将搜索词组合成一棵树。树的帮助量取决于搜索词中有多少重叠。我整理了一个基本的树实现(没有太多测试)作为起点:

Public Class WordSearchTree

    Private ReadOnly _branches As New Dictionary(Of Char, WordSearchTree)

    Public Function WordContainsTerm(ByVal word As String) As Boolean
        Return Not String.IsNullOrEmpty(word) AndAlso _
               Enumerable.Range(0, word.Length - 1) _
                         .Any(Function(i) WordContainsInternal(word, i))
    End Function

    Private Function WordContainsInternal(ByVal word As String, ByVal charIndex As Integer) As Boolean
        Return _branches.Count = 0 OrElse _
               (_branches.ContainsKey(word(charIndex)) AndAlso _
                charIndex < word.Length - 1 AndAlso _
                _branches(word(charIndex)).WordContainsInternal(word, charIndex + 1))
    End Function

    Public Shared Function BuildTree(ByVal words As IEnumerable(Of String)) As WordSearchTree
        If words Is Nothing Then Throw New ArgumentNullException("words")
        Dim ret As New WordSearchTree()
        For Each w In words
            Dim curTree As WordSearchTree = ret
            For Each c In w
                If Not curTree._branches.ContainsKey(c) Then
                    curTree._branches.Add(c, New WordSearchTree())
                End If
                curTree = curTree._branches(c)
            Next
        Next
        Return ret
    End Function

End Class

使用那棵树,您可以执行以下操作:

Dim keys As WordSearchTree = WordSearchTree.Build(keywordList)
termList.RemoveAll(AddressOf keys.WordContainsTerm)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多