【问题标题】:Improving O(n^2) algorithm改进 O(n^2) 算法
【发布时间】:2017-06-14 10:55:29
【问题描述】:

我有以下代码:

var keywordItems = adwordsService
  .ParseReport(report)
  .Where(e => e.Keyword.IndexOf('+') == -1);

var keywordTranslations = keywordTranslationService
  .GetKeywordTranslationsByClient(id);

model.KeywordItems = keywordItems
    .Where(e =>
    {
        int lastUnderscore = e.CampaignName.LastIndexOf('_');
        var identifer = e.CampaignName.Substring(lastUnderscore + 1);

        var translation = keywordTranslations
          .FirstOrDefault(t => t.translation == e.Keyword && 
                               t.LocalCombination_id == identifer);

        return translation == null;
    })
    .OrderBy(e => e.Keyword);

它接收一个数组,然后根据它们之前是否已经见过这些元素来过滤它们中的每一个。

但是,这运行起来很慢,因为有很多新元素,所以如果有人能指出我在这种情况下使用的最佳算法的正确方向,我会很高兴。

【问题讨论】:

  • 您有两个不同的输入 - keywordItemskeywordTranslations - 那么这里的 n 是什么?
  • 它们是两个大小大致相同的列表。

标签: c# arrays algorithm linq


【解决方案1】:

简单的连接将完成这项工作 - 它使用哈希集在集合之间进行匹配,这为您提供了 O(1) 的搜索操作:

from k in keywordItems
let identifer = k.CampaignName.Substring(k.CampaignName.LastIndexOf('_') + 1)
join t in keywordTranslations on
    new { k.Keyword, Id = identifer } equals
    new { Keyword = t.translation, Id = t.LocalCombination_id } into g
where !g.Any()
orderby k.Keyword
select k

要进一步提高性能,您可以将identifier 提取直接移动到密钥创建中。因此,您将省略引入新的范围变量。

【讨论】:

    【解决方案2】:

    我建议使用 散列,例如HashSet<T>Dictionary<T>。假设translationLocalCombination_id 的类型为string

      HashSet<Tuple<string, int>> keywordTranslations = 
        new HashSet<Tuple<string, string>>(keywordTranslationService
          .GetKeywordTranslationsByClient(id)
          .Select(t => new Tuple<string, int>(t.translation, t.LocalCombination_id)));
    
      model.KeywordItems = keywordItems
        .Where(e => !keywordTranslations.Contains(new Tuple<string, string>(
           e.Keyword,
           e.CampaignName.Substring(e.CampaignName.LastIndexOf('_') + 1))))
        .OrderBy(e => e.Keyword);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2014-02-09
      • 1970-01-01
      • 2014-04-30
      相关资源
      最近更新 更多