如何在两个非常大的列表中优化字符串搜索

时间:2017-01-07 23:45:30

标签: c# string

我有两个字符串列表:

private List<string> sortedList; //about 150k items
private List<string> mixedList; // about 200k items

其中一个是排序,另一个不是。

我使用以下代码 找到相交的单词

List<string> intersectingWords=new List<string>();
StringInvariantComparer stringComparer = new StringInvariantComparer();

foreach (var item in mixedList)
{
  int res = sortedList.BinarySearch(item, stringComparer);
  if (res >= 0 && !intersectingWords.Contains(item))
    intersectingWords.Add(item);
}



public class StringInvariantComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        return string.Compare(x, y, StringComparison.InvariantCultureIgnoreCase);
    }
}

不幸的是,这需要大约20-25秒,这太长时间了。

如果我将StringComparison类型更改为Ordinal,则会在1-2秒内完成,但无法找到30%的单词

您建议优化代码?

更新

如果我使用以下代码:

var wrongRes = sortedList.Intersect(mixedList).ToList();

结果:

enter image description here

如果我使用以下代码:

var upperMixed = new List<string>();
var upperSorted = new List<string>();
foreach (var item in mixedList)
    upperMixed.Add(item.ToUpper());
foreach (var item in sortedList)
    upperSorted.Add(item.ToUpper());
foreach (var word in upperSorted.Intersect(upperMixed))
{
    intersectingWords.Add(word.ToLower());
}

结果:

enter image description here

它们显然不一样:)

1 个答案:

答案 0 :(得分:1)

  1. List<string> intersectingWords替换为HashSet<string> intersectingWords - 对于Contains操作更好。
  2. 准备单词:将sortedListmixedList字符串保留为大写,并使用Ordinal comapre。如果您需要原始字符串,则可以保留2个字(正常和大写)的结构。比较大写并在intersectingWords
  3. 中添加普通单词