私は、あなたが両方ともキューの長さを最大化し、すべての値の合計を求めていると仮定します。
最も簡単な質問に最初に答えてください。Erlangのキューは、Erlangの通常のデータ構造ですので、辞書に格納する際に問題はありません。
実際には、OTP queue
モジュールは非常にシンプルですが、インターフェイスの過多は簡単に使い易くなります。 @ Nathonのエンキュー機能は、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
キューがいっぱいになると、キューの先頭にある最も古いメンバーが削除されます。空のキューがエラーを生成します。これは非常に単純な構造ですが、新しい要素が追加されるたびにキューがコピーされるので非効率です。リストを元に戻すことは、要素がそのリストから削除されるたびにリストがコピーされるときに役立ちません。しかし、それは簡単で、うまくいきます。
より効率的な構造は、キューをキューのフロントエンドとキューのリアエンドの2つのリストに分割することです。正面が空のとき、後端が反転して新しい正面になります。そう:
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
モジュールで使用されるデータ構造です。
要素の現在の合計を構造に追加して直接管理するのは非常に簡単です。
多くの場合、このような単純なデータ構造で作業する場合、提供されているモジュールをそのまま使用するように、独自のモジュールをロールするのと同じくらい簡単です。
キューの長さをチェックするifを持つことを考えていました。キューの場合:len(someQueue)> = 10最後のアイテムを削除し、新しいものを前面に追加します。私が持っている問題は、キューに値を追加することです。これはどうですか?最初にそれをリストに変換してリストを使用する:sum?ありがとう – jarryd
キューがいっぱいになると、最後のアイテムではなく最初のアイテムが削除されます。 (公平には、 "最後のアイテム"はリストの最後のアイテムではなく最後に追加されたアイテムです。) – knutin
@knutin: "最初の"アイテムと最後のアイテムは意味があります。ポイントはそれをFIFOにすることです。 – nmichaels