2009-08-20 1 views
7

Скажите, что у меня есть сводная коллекция значений, где я указываю размер коллекции и в любое время добавляется новое значение, все старые значения, превышающие этот заданный размер, выпадают. Очевидно (и я проверил это) лучший тип коллекции, чтобы использовать для этого поведения является Queue:Как вы получите первый и последний пункты в очереди?

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

Однако, если я хочу, чтобы вычислить разницу между первыми и последними элементами в очереди? Очевидно, что я не могу получить доступ к элементам по индексу. Но переключиться с очереди на что-то, что реализует IList, похоже, излишнее, как и запись нового класса Queue. Сейчас у меня есть:

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

что звонить ToArray() беспокоит меня, но лучшая альтернатива не приходит ко мне. Какие-либо предложения?

+0

Не имеет ли тип C# типа Dequeue? –

+0

Нет, у C# нет ни одного типа, .Net - это то, что имеет типы; и .Net не имеет типа Dequeue, он имеет тип Queue/Queue , который имеет метод Dequeue. –

ответ

14

Одна вещь, которую вы можете сделать, это иметь временную переменную, которая хранит значение, которое было просто выставлено в очередь, потому что это будет последнее значение, и поэтому к этой переменной можно получить доступ, чтобы получить это значение.

+0

Примерно в то же время, когда вы предоставили этот ответ, я понял, насколько простым было решение (что вы предложили, в основном). Хороший звонок! –

+0

Спасибо. Я рад, что могу дать хорошее предложение. – murgatroid99

2

Ваш лучший выбор - отслеживать последнее добавленное значение в Queue, а затем использовать функцию myQueue.Peek(), чтобы увидеть элемент «первый» (означающий следующий) в списке, не удаляя его.

1

Вы могли использовать Deque (d ouble- е nded очереди).

Я не думаю, что есть один встроенный в System.Collections (.Generic), но вот некоторая информация о структуре данных. Если вы применили что-то подобное, вы можете просто использовать PeekLeft() и PeekRight() для получения первого и последнего значений.

Конечно, вам будет необходимо, чтобы реализация вашего собственного дека предпочтительнее иметь дело с незыблемостью ToArray(). :)

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

10

Кажется мне, если вам нужен быстрый доступ к первому элементу в списке, то вы используете неправильную структуру данных. Вместо этого переключите LinkedList, который имеет свойства First и Last.

Обязательно добавляйте и удаляйте элементы в связанный список, используя AddLast и RemoveFirst для поддержания свойства Queue. Чтобы предотвратить непреднамеренное нарушение свойства Queue, подумайте о создании класса-оболочки вокруг связанного списка и выставлении только необходимых свойств из вашей очереди.

+0

Несчастливо, но лучше, чем отслеживать последнее добавленное за пределами структуры данных. –

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: Очевидно, что этот базовый класс должен быть более прочным, чтобы делать такие вещи, как защитить последнее свойство на пустой очереди. Но этого достаточно для основной идеи.

+0

Ha! Это почти VERBATIM код, который я только что написал.(Только различие - это имя класса, и я положил Last = item после base.Enqueue (item)). –

+0

Что происходит, когда последний элемент удален? Как бы вы установили 'Last' на второй последний элемент? – nawfal