यह वास्तव में आपके प्रश्न का उत्तर नहीं है, लेकिन मेरे पास एक वर्ग है जो एक संग्रह पर सामग्री () को बढ़ाता है। मैंने एक कतार को उप-वर्गित किया और एक ऐसा शब्दकोश जोड़ा, जो वस्तुओं की सूचियों के लिए हैशकोड को मैप करता है। Dictionary.Contains()
समारोह है हे (1) जबकि List.Contains()
, Queue.Contains()
और Stack.Contains()
हे (एन) कर रहे हैं।
शब्दकोश का मूल्य-प्रकार समान हैशकोड के साथ वस्तुओं को पकड़ने वाली एक कतार है। कॉल करने वाला कस्टम क्लास ऑब्जेक्ट की आपूर्ति कर सकता है जो IEqualityComparer को लागू करता है। आप इस पैटर्न का उपयोग स्टैक्स या सूचियों के लिए कर सकते हैं। कोड को बस कुछ बदलावों की आवश्यकता होगी।
private class HashQueue<T> : Queue<T>
{
private readonly IEqualityComparer<T> _comp;
public readonly Dictionary<int, Queue<T>> _hashes;
public HashQueue(IEqualityComparer<T> comp = null) : base()
{
this._comp = comp;
this._hashes = new Dictionary<int, Queue<T>>();
}
public HashQueue(int capacity, IEqualityComparer<T> comp = null) : base(capacity)
{
this._comp = comp;
this._hashes = new Dictionary<int, Queue<T>>(capacity);
}
public HashQueue(IEnumerable<T> collection, IEqualityComparer<T> comp = null) : base(collection)
{
this._comp = comp;
this._hashes = new Dictionary<int, Queue<T>>(base.Count);
foreach (var item in collection)
{
this.EnqueueDictionary(item);
}
}
public new void Enqueue(T item)
{
base.Enqueue(item);
this.EnqueueDictionary(item);
}
private void EnqueueDictionary(T item)
{
int hash = this._comp == null ? item.GetHashCode() : this._comp.GetHashCode(item);
Queue<T> temp;
if (!this._hashes.TryGetValue(hash, out temp))
{
temp = new Queue<T>();
this._hashes.Add(hash, temp);
}
temp.Enqueue(item);
}
public new T Dequeue()
{
T result = base.Dequeue();
int hash = this._comp == null ? result.GetHashCode() : this._comp.GetHashCode(result);
Queue<T> temp;
if (this._hashes.TryGetValue(hash, out temp))
{
temp.Dequeue();
if (temp.Count == 0)
this._hashes.Remove(hash);
}
return result;
}
public new bool Contains(T item)
{
int hash = this._comp == null ? item.GetHashCode() : this._comp.GetHashCode(item);
return this._hashes.ContainsKey(hash);
}
public new void Clear()
{
foreach (var item in this._hashes.Values)
item.Clear();
this._hashes.Clear();
base.Clear();
}
}
मेरा सरल परीक्षण बताता है कि मेरी HashQueue.Contains()
तुलना में बहुत तेजी से चलता हैQueue.Contains()
। 10,000 से काउंट सेट के साथ टेस्ट कोड चलाने में हैशक्यू संस्करण के लिए 0.00045 सेकंड और क्यू संस्करण के लिए 0.37 सेकंड लगते हैं। 100,000 की गिनती के साथ, हाशिक्यू संस्करण 0.0031 सेकंड लेता है जबकि क्यू 36.38 सेकंड लेता है!
यहाँ मेरा परीक्षण कोड है:
static void Main(string[] args)
{
int count = 10000;
{
var q = new HashQueue<int>(count);
for (int i = 0; i < count; i++)
q.Enqueue(i);
System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
bool contains = q.Contains(i);
}
sw.Stop();
Console.WriteLine(string.Format("HashQueue, {0}", sw.Elapsed));
}
{
var q = new Queue<int>(count);
for (int i = 0; i < count; i++)
q.Enqueue(i);
System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
bool contains = q.Contains(i);
}
sw.Stop();
Console.WriteLine(string.Format("Queue, {0}", sw.Elapsed));
}
Console.ReadLine();
}