The Most Efficient Implementation of UniqueQueue and UniqueReplacementQueue Collections in .NET(.NET 中 UniqueQueue 和 UniqueReplacementQueue 集合的最有效实现)
问题描述
考虑到 Enqueue 和 Dequeue 操作的速度同样重要这一事实,.NET 中 UniqueQueue 和 UniqueReplacementQueue 集合的最有效(就速度而言)实现是什么.
What is the most efficient (in terms of speed) implementation of UniqueQueue and UniqueReplacementQueue collections in .NET considering the fact that the speed of Enqueue and Dequeue operations is equally important.
UniqueQueue 是一个不可能重复的队列.因此,如果我将一个元素推送到队列中,它只会在队列中不存在的情况下添加.
UniqueQueue is a queue where duplicates are not possible. So if I push an element to the queue it is added in only case it doesn't already exist in the queue.
UniqueReplacementQueue 是一个也不可能出现重复的队列.不同之处在于,如果我推送队列中已经存在的元素,它将替换相同位置的现有元素.这对引用类型很有意义.
UniqueReplacementQueue is a queue where duplicates are not possible either. The difference is that if I push an element which already exists in the queue, it replaces the existing element at the same position. It makes sense for reference types.
我目前对 UniqueQueue 和 UniqueReplacementQueue 的实现:
My current implementation of UniqueQueue and UniqueReplacementQueue:
sealed class UniqueQueue<T> : IQueue<T>
{
readonly LinkedList<T> list;
readonly IDictionary<T, int> dictionary;
public UniqueQueue(LinkedList<T> list, IDictionary<T, int> dictionary)
{
this.list = list;
this.dictionary = dictionary;
}
public int Length
{
get { return list.Count; }
}
public T Dequeue()
{
if (list.Count == 0)
{
throw new InvalidOperationException("The queue is empty");
}
var element = list.First.Value;
dictionary.Remove(element);
list.RemoveFirst();
return element;
}
public void Enqueue(T element)
{
dictionary[element] = 0;
if (dictionary.Count > list.Count)
{
list.AddLast(element);
}
}
}
sealed class UniqueReplacementQueue<T> : IQueue<T>
{
readonly LinkedList<T> list;
readonly IDictionary<T, T> dictionary;
public UniqueReplacementQueue(LinkedList<T> list, IDictionary<T, T> dictionary)
{
this.list = list;
this.dictionary = dictionary;
}
public int Length
{
get { return list.Count; }
}
public T Dequeue()
{
if (list.Count == 0)
{
throw new InvalidOperationException("The queue is empty");
}
var element = dictionary[list.First.Value];
dictionary.Remove(element);
list.RemoveFirst();
return element;
}
public void Enqueue(T element)
{
dictionary[element] = element;
if (dictionary.Count > list.Count)
{
list.AddLast(element);
}
}
}
推荐答案
这已经很老了,但是有一个内部 HashSet 和 Queue 的类怎么样.Enqueue firsts 的自定义方法尝试将其添加到哈希集中.如果 HashSet.Add 调用返回 false,我们不会将其加入队列.如果集合的大小足以容纳所有元素,则 HashSet.Add() 是 O(1) 操作.
This is pretty old, but how about a class that has an internal HashSet, and Queue. A custom method for Enqueue firsts tries to add it to the hashset. if the HashSet.Add call returns false, we do not enqueue it. HashSet.Add() is an O(1) operation if the set is of a size large enough to hold all elements.
如果您担心,唯一的缺点是内存使用.这是一个实现:
The only drawback to this is memory usage if this is a concern for you. Here is an implementation:
public class UniqueQueue<T> : IEnumerable<T> {
private HashSet<T> hashSet;
private Queue<T> queue;
public UniqueQueue() {
hashSet = new HashSet<T>();
queue = new Queue<T>();
}
public int Count {
get {
return hashSet.Count;
}
}
public void Clear() {
hashSet.Clear();
queue.Clear();
}
public bool Contains(T item) {
return hashSet.Contains(item);
}
public void Enqueue(T item) {
if (hashSet.Add(item)) {
queue.Enqueue(item);
}
}
public T Dequeue() {
T item = queue.Dequeue();
hashSet.Remove(item);
return item;
}
public T Peek() {
return queue.Peek();
}
public IEnumerator<T> GetEnumerator() {
return queue.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return queue.GetEnumerator();
}
}
尽可能使用 HashSet,因为它通常更快.如果 .NET 的维护者将这些方法标记为虚拟方法,这可能会更好,但可惜我们到了.
The HashSet is used whenever it can because it is typically faster. This could be nicer if the maintainers of .NET marked these methods as virtual, but alas here we are.
这篇关于.NET 中 UniqueQueue 和 UniqueReplacementQueue 集合的最有效实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:.NET 中 UniqueQueue 和 UniqueReplacementQueue 集合的最有效实现


- 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
- 如何用自己压缩一个 IEnumerable 2022-01-01
- MoreLinq maxBy vs LINQ max + where 2022-01-01
- 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
- Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
- C#MongoDB使用Builders查找派生对象 2022-09-04
- WebMatrix WebSecurity PasswordSalt 2022-01-01
- C# 中多线程网络服务器的模式 2022-01-01
- 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
- 输入按键事件处理程序 2022-01-01