2010-11-29 8 views
1

N値を保持するキューを設定するには? Nに達すると、最後の項目を削除し、キューの先頭に値を追加します。キューサイズの制限を設定する

if文でこれを行う必要がありますか?

また、新しい項目が追加されたときにキュー内の値を計算したいと考えています。例えばキューのすべての値を追加します。あなたが実際にアイテムを合計したくない場合は、代わりにlists:foldlを使用することができます

enqueue(Value, Queue) -> 
    Pushed = queue:in(Value, Queue), 
    Sum = fun (Q) -> lists:sum(queue:to_list(Q)) end, 
    case queue:len(Pushed) of 
     Len when Len > 10 -> 
      Popped = queue:drop(Pushed), 
      {Popped, Sum(Popped)}; 
     _ -> 
      {Pushed, Sum(Pushed)} 
    end. 

、または単に上で直接操作を行うための機能を記述します。コメントは考える

答えて

4

、これはそれを行いますキュー。

+0

キューの長さをチェックするifを持つことを考えていました。キューの場合:len(someQueue)> = 10最後のアイテムを削除し、新しいものを前面に追加します。私が持っている問題は、キューに値を追加することです。これはどうですか?最初にそれをリストに変換してリストを使用する:sum?ありがとう – jarryd

+0

キューがいっぱいになると、最後のアイテムではなく最初のアイテムが削除されます。 (公平には、 "最後のアイテム"はリストの最後のアイテムではなく最後に追加されたアイテムです。) – knutin

+0

@knutin: "最初の"アイテムと最後のアイテムは意味があります。ポイントはそれをFIFOにすることです。 – nmichaels

6

私は、あなたが両方ともキューの長さを最大化し、すべての値の合計を求めていると仮定します。

最も簡単な質問に最初に答えてください。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モジュールで使用されるデータ構造です。

要素の現在の合計を構造に追加して直接管理するのは非常に簡単です。

多くの場合、このような単純なデータ構造で作業する場合、提供されているモジュールをそのまま使用するように、独自のモジュールをロールするのと同じくらい簡単です。

+0

それはテストされていないが動作する必要があることを忘れた – rvirding

+0

その偉大な答えをありがとうが、私がやって見ていたものに比べて強烈な方法です。私はerlangで標準キューを使用します。次にリストに変換し、を使用して値を追加します。リスト:合計。 ;) – jarryd

関連する問題