यह उत्तर केली के समान है लेकिन एक परीक्षण कोड उदाहरण है। चूंकि एन का आकार छोटा < 100 है, इसलिए मैंने एक साधारण प्रविष्टि प्रकार का उपयोग किया, यदि बाइनरी सर्च लुकअप के साथ संशोधित किया गया है तो आइटम की संख्या कुछ (गैर-अनुकूलित) मान (उदा। 20 आइटम) से ऊपर है। मैंने इसका उपयोग दिखाने के लिए नमूना कंसोल ऐप (सी #) शामिल किया है। मैंने यह सुनिश्चित करने के लिए संक्षेप में इसका परीक्षण किया कि यह काम करता है, लेकिन इस समय मैंने इसका पूर्ण विश्लेषण नहीं किया। यह संरचना स्मृति उपयोग को कम करने के लिए अनुकूलित है।
public class TopNStructure<T> : IEnumerable<T> where T : IComparable<T>
{
private const int SizeForLinearOrBinaryInsert = 20;
private int _maxSize;
private int _currentSize;
private T[] _items;
private IComparer<T> _comparer;
/// <summary>
/// The number of items
/// </summary>
public int Count { get { return _currentSize; } }
public TopNStructure(int maxSize, IComparer<T> comparer)
{
if (maxSize <= 0)
{
throw new ArgumentOutOfRangeException("Max size must be a postive, non-zero value");
}
_maxSize = maxSize;
_currentSize = 0;
_items = new T[maxSize];
_comparer = comparer;
}
public TopNStructure(int maxSize)
: this(maxSize, Comparer<T>.Default) { }
/// <summary>
/// Adds an item to this structure
/// </summary>
/// <param name="item">The item to add</param>
/// <returns>True if the item was added, false otherwise</returns>
public bool Add(T item)
{
if (_currentSize == 0)
{
_items[0] = item;
}
else if (_currentSize == _maxSize)
{
if (_comparer.Compare(_items[_currentSize - 1], item) <= 0)
{
return false;
}
else
{
Insert(item);
return true;
}
}
else if (_currentSize == 1)
{
if (_comparer.Compare(_items[0], item) <= 0)
{
_items[1] = item;
}
else
{
_items[1] = _items[0];
_items[0] = item;
}
}
else
{
if (_comparer.Compare(_items[_currentSize - 1], item) <= 0)
{
_items[_currentSize] = item;
}
else
{
Insert(item);
}
}
_currentSize++;
return true;
}
/// <summary>
/// Insert the item into the data structure
/// </summary>
/// <param name="item">The item to insert</param>
private void Insert(T item)
{
int start = 0;
if (_currentSize >= SizeForLinearOrBinaryInsert)
{
start = Array.BinarySearch<T>(_items, 0, _currentSize, item, _comparer);
if (start < 0)
{
start = ~start;
}
ShiftAndInsert(item, start, _currentSize);
return;
}
else
{
for (int i = start; i < _currentSize; i++)
{
if (_comparer.Compare(_items[i], item) > 0)
{
ShiftAndInsert(item, i, _currentSize);
return;
}
}
_items[_currentSize] = item;
}
}
/// <summary>
///
/// </summary>
/// <param name="index"></param>
/// <param name="maxIndex"></param>
private void ShiftAndInsert(T item, int index, int maxIndex)
{
if (maxIndex >= _maxSize)
{
maxIndex = _maxSize - 1;
}
for (int i = maxIndex; i > index; i--)
{
_items[i] = _items[i - 1];
}
_items[index] = item;
}
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)_items).GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _items.GetEnumerator();
}
}
static void Main(string[] args)
{
TopNStructure<double> data = new TopNStructure<double>(25);
Random rand = new Random(132151);
for (int i = 0; i < 50; i++)
{
double value = rand.NextDouble();
data.Add(value);
}
int j = 0;
foreach (double value in data)
{
Console.WriteLine("{0} {1}", j, value);
j++;
}
Console.ReadKey();
}
प्राथमिकता कतार के बारे में कैसे? यदि एक ढेर द्वारा समर्थित, यह बहुत कुशल होगा। सुनिश्चित नहीं है कि यह मूल .NET संग्रह है, हालांकि – alrikai
यदि एन अपेक्षाकृत छोटा है, तो केवल प्रविष्टियां हैं, और आप उन्हें क्रमबद्ध क्रम में रखना चाहते हैं, प्रत्येक सम्मिलन पर एक बबल प्रकार खराब नहीं है। –
क्या उन वस्तुओं का ट्रैक रखना संभव है जो वास्तव में मूल्य को बदलते समय बदलते हैं? क्या वे केवल एक बार प्रति पुनरावृत्ति (अंतिम शीर्ष-एन प्रकार से पहले) अपडेट किए जाते हैं? – wildplasser