Из вашего запроса я предполагаю, что вы оба хотите максимизировать длину очереди и получить сумму всех значений.
Сначала ответьте на свой самый простой вопрос: очереди Erlang, однако вы хотите их представитьявляются обычными структурами данных Erlang, поэтому нет проблем с их сохранением в словаре.
Модуль OTP queue
на самом деле очень прост, но множество интерфейсов легко запутывает его использование.Функция постановки @ Натона может быть значительно более эффективной, если не использовать непосредственно структуру данных queue
, а определить собственную структуру данных, которая включает очередь и ее текущую длину, {Length,Queue}
.Если сумма важна, вы можете даже включить ее.
Представления в очереди очень просты, поэтому очень легко написать свою собственную специализированную форму.
Самый простой способсохранить очередь в списке, взять элементы из головы и добавить новые элементы в конец.Итак:
new(Max) when is_integer(Max), Max > 0 -> {0,Max,[]}. %Length, Max and Queue list
take({L,M,[H|T]}) -> {H,{L-1,M,T}}.
add(E, {L,M,Q}) when L < M ->
{L+1,M,Q ++ [E]}; %Add element to end of list
add(E, {M,M,[H|T]}) -
{M,M,T ++ [E]}. %Add element to end of list
Когда очередь заполняется, самый старый элемент, находящийся в начале очереди, удаляется.Пустая очередь генерирует ошибку.Это очень простая структура, но она неэффективна, поскольку очередь копируется при каждом добавлении нового элемента.Изменение списка не помогает, так как тогда список копируется каждый раз, когда элемент удаляется из него.Но это просто, и это работает.
Гораздо более эффективная структура состоит в том, чтобы разделить очередь на два списка: внешний конец очереди и задний конец очереди.Задний конец полностью изменен и становится новым фронтом, когда фронт пуст.Итак:
new(Max) when is_integer(Max), Max > 0 ->
{0,Max,[],[]}. %Length, Max, Rear and Front
take({L,M,R,[H|T]}) -> {H,{L-1,M,R,T}};
take{{L,M,R,[]}) when L > 0 ->
take({L,M,[],lists:reverse(R)}). %Move the rear to the front
add(E, {L,M,R,F}) when L < M ->
{L+1,M,[R|E],F}; %Add element to rear
add(E, {M,M,R,[H|T]}) ->
{M,M,[R|E],T}; %Add element to rear
add(E, {M,M,R,[]}) ->
add(E, {M,M,[],lists:reverse(R)}). %Move the rear to the front
Снова, когда очередь заполняется, самый старый элемент, находящийся в начале очереди, удаляется, и пустая очередь выдает ошибку.Это структура данных, используемая в модуле queue
.
Было бы очень легко добавить текущую сумму элементов в структуру и управлять ею напрямую.
Часто при работедля таких простых структур данных, как этот, так же просто свернуть свой собственный модуль, как и для использования предоставленного.