更改Dictionary <k,v>?</k,v>的最快方法是什么

时间:2012-11-22 12:28:54

标签: c# .net algorithm

这是一个算法问题。

我有Dictionary<object,Queue<object>>。每个队列中都包含一个或多个元素。我想删除字典中只有一个元素的所有队列。最快的方法是什么?

伪代码:foreach(item in dict) if(item.Length==1) dict.Remove(item);

在循环中很容易做到(当然不是foreach),但我想知道哪种方法是最快的方法。

为什么我需要它:我使用该字典在大量对象中查找重复元素。字典中的Key是对象的哈希值,Value是使用相同哈希值找到的所有对象的队列。由于我只需要重复项,因此我需要删除相关队列中只有一个对象的所有项目。

更新

重要的是要知道,在常规情况下,大量对象中只有几个重复项。我们假设1%或更少。因此,将字典保留为原样可能会更快,并且从scatch创建一个新的,只有第一个中的选定元素...然后完全解除第一个字典。我认为这取决于特定算法中使用的计算Dictionary类的方法的复杂性。

我真的希望在理论层面上看到这个问题,因为作为一名教师,我想与学生讨论。我自己没有提供任何具体的解决方案,因为我觉得它很容易实现。问题是哪种方法最好,最快。

3 个答案:

答案 0 :(得分:2)

var itemsWithOneEntry = dict.Where(x => x.Value.Count == 1)
                            .Select(x => x.Key)
                            .ToList();

foreach (var item in itemsWithOneEntry) {
    dict.Remove(item));
}

答案 1 :(得分:1)

它不是试图优化集合的遍历如何优化集合的内容,以便它只包含重复项?这需要更改您的收集算法,而不是像这样

var duplicates = new Dictionary<object,Queue<object>>;
var possibleDuplicates = new Dictionary<object,object>();
foreach(var item in original){
    if(possibleDuplicates.ContainsKey(item)){
       duplicates.Add(item, new Queue<object>{possibleDuplicates[item],item});
       possibleDuplicates.Remove(item);
    } else if(duplicates.ContainsKey(item)){
       duplicates[item].Add(item);
    } else {
       possibleDuplicates.Add(item);
    }
}

答案 2 :(得分:0)

请注意,在您需要使代码变得比实际需要的更复杂之前,您应该在实际场景中测量这对性能的影响。大多数想象中的性能问题实际上并不是代码速度慢的真正原因。

但假设您确实发现通过避免线性搜索长度为1的队列可以获得速度优势,您可以使用名为索引的技术解决此问题。

除了包含所有队列的字典外,还维护一个仅包含长度为1的队列的索引容器(可能是另一个字典),因此当您需要它们时,它们已经单独提供。

为此,您需要增强修改队列长度的所有操作,以便它们具有更新索引容器的副作用。

一种方法是定义一个类ObservableQueue。这将是Queue的一个瘦包装,除了它还有一个ContentsChanged事件,当队列中的项目数发生变化时会触发该事件。在任何地方使用ObservableQueue代替普通Queue

然后,当您创建新队列时,在其ContentsChanged事件上登记一个处理程序,该处理程序检查队列是否只有一个项目。基于此,您可以在索引容器中插入或删除它。