【问题标题】:Efficiently eliminate subset of strings in C# [closed]有效地消除 C# 中的字符串子集 [关闭]
【发布时间】:2017-10-13 00:33:19
【问题描述】:

我有一组唯一字符串(数千个)和另一组更大的唯一字符串(超过一百万个)。两个集合中的字符串长度或多或少相同(少于 10 个字符,它是用作 id 的字符串)。我需要从较小的集合中删除字符串的子集,只保留较大集合中存在的字符串。换句话说,如果这样的字符串存在于较大的集合中,我将其保留在较小的集合中,否则我需要将其从较小的集合中删除。 这两个集合的容器可以是任何类型的 (C#),也可以只是简单的数组。问题是:我需要使用最高效(按时间)的方式从较小的容器中删除较大容器中不存在的字符串。

【问题讨论】:

  • 那么到目前为止,您尝试了哪些方法?你有任何代码说明你做了什么吗?
  • 你已经很好地解释了你需要什么。您能否解释一下到目前为止您已经尝试过什么以及您想要进行哪些改进?
  • 使用数组你不会超过O(N*M)的性能成本(N是小集合的大小,M是大集合的大小我>)。由于需要迭代。如果你想让这个更快,考虑改变数据结构,如果更大的集合是一个哈希表,它会让这个任务O(N)
  • 为什么这被标记为太宽泛了??
  • @KeithNicholas 因为这个问题太宽泛了。

标签: c# string performance


【解决方案1】:

Linq 是显而易见的选择,只需使用

var list = smallList.Intersect(bigList).ToList();

另外,如果您想了解它是如何完成的,不妨看看 Jon Skeets 博客关于实现 Intersect。

https://codeblog.jonskeet.uk/2010/12/30/reimplementing-linq-to-objects-part-16-intersect-and-build-fiddling/

例子

 var random = new Random();
 var bigList = Enumerable.Range(1, 1000000).Select(n => n.ToString());
 var smallList = Enumerable.Range(1, 1000000)
       .OrderBy(i => random.Next())
       .Take(1000)
       .Select(i => (i*2).ToString());

 var stopwatch = new Stopwatch();
 stopwatch.Start();

 var list = smallList.Intersect(bigList).ToList();

 stopwatch.Stop();

 Console.WriteLine($"{list.Count()} in {stopwatch.ElapsedMilliseconds}ms");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    相关资源
    最近更新 更多