2009-08-20 25 views
7

Powiedzmy, że mam zbiór ciągłych wartości, w których określam rozmiar kolekcji i za każdym razem, gdy dodawana jest nowa wartość, stare wartości przekraczające ten określony rozmiar są pomijane. Oczywiście (i Przetestowałem to) najlepszy rodzaj kolekcji do korzystania z tego zachowania jest kolejka:Jak uzyskać pierwsze i ostatnie elementy w kolejce?

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

Jednak co, jeśli chcę obliczyć różnicę między pierwszym i ostatnim pozycji w kolejce? Oczywiście nie mogę uzyskać dostępu do elementów według indeksu. Ale przejście z kolejki na coś, co implementacja ILista wydaje się przesadą, podobnie jak pisanie nowej klasy podobnej do kolejki. Teraz mam:

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

To zadzwoń do ToArray() denerwuje mnie, ale lepsza alternatywa nie przychodzi do mnie. Jakieś sugestie?

+0

Czy nie ma C# typu Dequeue? –

+0

Nie, C# nie ma żadnego typu, .Net jest tym, co ma typy; i .Net nie ma typu Dequeue, ma typ Queue/Queue , który ma metodę Dequeue. –

Odpowiedz

14

Jedną z rzeczy, którą można zrobić, to mieć tymczasową zmienną, która przechowuje wartość, która była właśnie zakolowyzowana, ponieważ będzie to ostatnia wartość, a więc można uzyskać dostęp do zmiennej, aby uzyskać tę wartość.

+0

Mniej więcej w tym samym czasie, w którym dostarczyłeś tę odpowiedź, zdałem sobie sprawę, jak proste może być rozwiązanie (co zasugerowałeś w zasadzie). Dobra decyzja! –

+0

Dzięki. Cieszę się, że mogłem dać dobrą sugestię. – murgatroid99

2

Najlepiej byłoby śledzić ostatnią wartość dodaną do Queue, a następnie użyć funkcji myQueue.Peek(), aby zobaczyć "pierwszy" (co oznacza następny) element na liście bez usuwania go.

1

Ty mógłby użyć deque (d ouble- e wyładowanych kolejka).

Nie sądzę, że jest jeden wbudowany w System.Collections (.Generic), ale oto niektóre informacje na temat struktury danych. Jeśli zaimplementowałeś coś takiego, możesz po prostu użyć PeekLeft() i PeekRight(), aby uzyskać pierwszą i ostatnią wartość.

Oczywiście, od Ciebie zależy, czy wdrożenie własnego portfela jest lepsze od radzenia sobie z nieprzyjemnością ToArray(). :)

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

10

Wydaje mi się, jeśli potrzebujesz szybkiego dostępu do pierwszej pozycji na liście, a następnie używasz złą strukturę danych. Zamiast tego należy zamiast tego zamienić listę typu LinkedList, która z łatwością ma właściwości First i Last.

Upewnij się, że tylko dodajesz i usuwasz elementy do połączonej listy przy użyciu AddLast i RemoveFirst, aby zachować właściwość kolejki. Aby zapobiec nieumyślnemu naruszeniu właściwości kolejki, należy rozważyć utworzenie klasy opakowującej wokół połączonej listy i ujawnienie tylko potrzebnych właściwości z kolejki.

+0

Niefortunne, ale lepsze niż śledzenie ostatnio dodanych poza samą strukturą danych. –

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: Oczywiście ta podstawowa klasa powinna być bardziej stabilna, aby robić takie rzeczy jak chronić Ostatnie nieruchomości na pustej kolejki. Ale to powinno wystarczyć na podstawową ideę.

+0

Ha! To jest prawie WERBATIM, który właśnie napisałem.(Jedyną różnicą jest nazwa klasy i umieszczam Last = item po base.Enqueue (element)). –

+0

Co się stanie, gdy ostatni element zostanie usunięty? Jak zatem ustawić "Last" na drugi ostatni element? – nawfal

Powiązane problemy