2009-08-20 1 views
7

Angenommen, ich habe eine rollende Sammlung von Werten, in der ich die Größe der Sammlung festlege, und jedes Mal, wenn ein neuer Wert hinzugefügt wird, werden alle alten Werte über diese angegebene Größe hinaus abgelegt. Offensichtlich (und ich habe diese getestet), um die beste Art der Sammlung für dieses Verhalten zu verwenden, ist eine Queue:Wie erhalten Sie die ersten und letzten Einträge in einer Warteschlange?

myQueue.Enqueue(newValue) 
If myQueue.Count > specifiedSize Then myQueue.Dequeue() 

Was aber, wenn ich den Unterschied zwischen den ersten und letzten Elementen in der Warteschlange berechnet werden soll? Offensichtlich kann ich nicht auf die Artikel nach Index zugreifen. Aber das Umschalten von einer Warteschlange zu etwas, das IList implementiert, erscheint wie ein Overkill, genauso wie das Schreiben einer neuen Queue-ähnlichen Klasse. Gerade jetzt ich habe:

Dim firstValue As Integer = myQueue.Peek() 
Dim lastValue As Integer = myQueue.ToArray()(myQueue.Count - 1) 
Dim diff As Integer = lastValue - firstValue 

Das zu ToArray() nennen stört mich, aber eine bessere Alternative kommt nicht zu mir. Irgendwelche Vorschläge?

+0

Hat C# keinen Dequeue-Typ? –

+0

Nein, C# hat keinen Typ, .Net hat was Typen; und .Net hat keinen Dequeue-Typ, es hat einen Queue/Queue Typ, der eine Dequeue-Methode hat. –

Antwort

14

Eine Sache, die Sie tun können, ist eine temporäre Variable, die den Wert speichert, der gerade in die Warteschlange gestellt wurde, da dies der letzte Wert ist und auf die Variable zugegriffen werden kann, um diesen Wert zu erhalten.

+0

Ungefähr zur gleichen Zeit, als Sie diese Antwort gaben, wurde mir klar, wie einfach die Lösung (was Sie im Grunde vorgeschlagen haben) wäre. Guter Anruf! –

+0

Danke. Ich bin froh, dass ich einen guten Vorschlag machen konnte. – murgatroid99

2

Ihre beste Wette wäre, den letzten Wert zu behalten, der dem Queue hinzugefügt wird, und dann die myQueue.Peek() Funktion zu verwenden, um das "erste" (Bedeutung next) Element in der Liste zu sehen, ohne es zu entfernen.

1

Sie könnte verwenden, um eine deque (d ouble- e NDED Warteschlange).

Ich glaube nicht, dass in System.Collections (.Generic) ein eingebaut ist, aber hier ist ein paar Informationen über die Datenstruktur. Wenn Sie so etwas implementiert haben, können Sie PeekLeft() und PeekRight() verwenden, um die ersten und letzten Werte zu erhalten.

Natürlich liegt es an Ihnen, ob die Implementierung Ihrer eigenen Deque dem Umgang mit der Unsexiness von ToArray() vorzuziehen ist. :)

http://www.codeproject.com/KB/recipes/deque.aspx

10

mir scheint, wenn Sie einen schnellen Zugriff auf das erste Element in der Liste benötigen, dann sind Sie die falsche Datenstruktur. Wechseln Sie stattdessen eine LinkedList, die die Eigenschaften First und Last aufweist.

Stellen Sie sicher, dass Sie der verknüpften Liste nur Elemente hinzufügen und entfernen, die AddLast und RemoveFirst verwenden, um die Warteschlangeneigenschaft beizubehalten. Um zu verhindern, dass Sie versehentlich die Queue-Eigenschaft verletzen, sollten Sie eine Wrapperklasse um die verknüpfte Liste erstellen und nur die Eigenschaften anzeigen, die Sie in Ihrer Warteschlange benötigen.

+0

Unglücklicherweise, aber besser, als den letzten außerhalb der Datenstruktur selbst hinzugefügten. –

4
public class LastQ<T> : Queue<T> 
{ 
    public T Last { get; private set; } 

    public new void Enqueue(T item) 
    { 
     Last = item; 
     base.Enqueue(item); 
    } 
} 

Edit: Offensichtlich ist diese Basisklasse sollte robust sein, Dinge zu tun, wie die letzte Eigenschaft auf einer leeren Warteschlange zu schützen. Aber das sollte für die Grundidee ausreichen.

+0

Ha! Das ist fast VERBATIM der Code den ich gerade geschrieben habe.(Einziger Unterschied ist der Klassenname und ich habe Last = item nach base.Enqueue (item)). –

+0

Was passiert, wenn das letzte Element entfernt wird? Wie würden Sie 'Last' dann auf das zweitletzte Element setzen? – nawfal

Verwandte Themen