【问题标题】:Faster way to find first occurence of String in list在列表中查找第一次出现的字符串的更快方法
【发布时间】:2017-04-08 08:58:36
【问题描述】:

我有一个方法,可以在单词列表中找到第一个出现的位置。 wordSet - 一组单词,我需要检查 该列表是文本的表示,因此按顺序排列的单词,该文本具有。 所以如果pwWords 有吸元素{This,is,good,boy,and,this,girl,is,bad} 并且wordSet 具有{this,is} 方法应该只为前两个元素添加true。 我的问题是:有没有更快的方法来做到这一点? 因为如果pwWords 拥有超过百万个元素,而wordSet 超过 10 000 个元素,它的运行速度就会很慢。

public List<bool> getFirstOccurances(List<string> pwWords)
    {
        var firstOccurance = new List<bool>();
        var wordSet = new List<String>(WordsWithFDictionary.Keys);
        foreach (var pwWord in pwWords)
        {
            if (wordSet.Contains(pwWord))
            {
                firstOccurance.Add(true);
                wordSet.Remove(pwWord);
            }
            else
            {
                firstOccurance.Add(false);
            }
        }
        return firstOccurance;
    }

【问题讨论】:

  • 如果搜索不止一次,那么您可以使用HashSet&lt;string&gt; 而不是List - 搜索会比List 更快

标签: c# list optimization set


【解决方案1】:

另一种方法是将HashSet 用于wordSet

public List<bool> getFirstOccurances(List<string> pwWords)
{
    var wordSet = new HashSet<string>(WordsWithFDictionary.Keys);
    return pwWords.Select(word => wordSet.Contains(word)).ToList();
}

HashSet.Contains 算法是 O(1),其中List.Contains 将循环所有项目,直到找到项目。

为了获得更好的性能,如果可能,您可以只创建一次wordSet

public class FirstOccurances
{
    private HashSet<string> _wordSet;

    public FirstOccurances(IEnumerable<string> wordKeys)
    {
        _wordSet = new HashSet<string>(wordKeys);
    }

    public List<bool> GetFor(List<string> words)
    {
        return words.Select(word => _wordSet.Contains(word)).ToList();
    }
}

那就用吧

var occurrences = new FirstOccurances(WordsWithFDictionary.Keys);

// Now you can effectively search for occurrences multiple times
var result = occurrences.GetFor(pwWords);
var anotherResult = occurrences.GetFor(anotherPwWords);

因为pwWords 的项目可以独立检查是否出现,如果未导入项目的顺序,您可以尝试使用并行 LINQ

public List<bool> GetFor(List<string> words)
{
    return words.AsParallel().Select(word => _wordSet.Contains(word)).ToList();
}

【讨论】:

    猜你喜欢
    • 2021-08-14
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 2016-06-27
    相关资源
    最近更新 更多