2012-05-06 10 views
10

add()は重複を無視すると考えられますが、出力に重複があります。重複はどのように保存しないのですか?重複を無視するようにJava Priority Queueを設定するにはどうすればよいですか?

また、優先度キューが2つの要素が重複しているかどうかを確認する方法も知りたいと思います。私はそれがコンパレータequalsを使用していると推測しているが、私はちょうど確信したい。

おかげ

答えて

9

PriorityQueue Javadocから一部である:

このキュー注文要素は(匹敵参照)のいずれか、それらの自然な順序に従って指定された構築時に指定された順序に従って、又は比較器によれば、どのコンストラクタが使用されているかによって異なります。

したがって、PriorityQueueはComparator(コンストラクタ引数として指定した場合)を使用するか、compareTo(...)メソッドを使用します(要素はComparableインターフェイスを実装する必要があります)。

PriorityQueueは重複を許可します。したがって、それを避けたい場合は、独自のバージョンのQueueを実装する必要があります。あなたは非常にエレガントな方法を見つけることができます、それを行う方法"Effective Java", page 85。代わりに、PriorityQueueクラスを拡張してaddメソッドをオーバーライドすることもできます(これはcontains(...)チェックを入れるのに最適な場所です)。

4

はJavaでPriorityQueueは、要素を複製についても一切制限はありません。 2つの同一アイテムが優先キューに同時に存在しないようにするには、最も簡単な方法は、別のSetを優先キューと並列に保つことです。優先度キューに要素を挿入するたびに、その要素にすでに要素が含まれているかどうかを確認し、設定されていない場合はそれを設定キューと優先度キューの両方に追加できます。優先度キューから要素を削除すると、その要素もセットから削除されます。

また、プライオリティキューで実行する操作と、同等性がどのように定義されているかによって、TreeSetに置き換えることも可能です優先度の高いキューでアクセスし、重複を許可しない操作。ここ

+0

誰かがTreeSetを使用しない理由を追加すると便利かもしれません。 (TreeSetのpeek操作はO(logn)ですが、PriorityQueueは一定ですが、頭をポップするのはTreeSetで*わずかに高価です) – JMess

3

セットは重複を無視する唯一のものです。リストとキューはリストではありません。 (LinkedListはキューです)

重複を削除する場合は、取得するエントリが前のものと同じかどうかを確認して無視します。あなたは好きなように比較することができます。 ;)

+1

これを行うには、比較関数が等価と一致する必要があります。場合。例えば、開いた状態のQが、互いに関連していない重みと等価性をノード上で比較する、多状態A *検索。 –

+0

@LaurentGrégoireあなたは大文字小文字のように構築することができますが、compareTo状態のjavadocを指定するとequalsと一貫していなければなりません。 –

5
import java.util.PriorityQueue; 

public class NoDuplicates<E> extends PriorityQueue<E> 
{ 
    @Override 
    public boolean offer(E e) 
    { 
     boolean isAdded = false; 
     if(!super.contains(e)) 
     { 
      isAdded = super.offer(e); 
     } 
     return isAdded; 
    } 
    public static void main(String args[]) 
    { 
     PriorityQueue<Integer> p = new NoDuplicates<Integer>(); 
     p.add(10); 
     p.add(20); 
     p.add(10); 
     for(int i =0;i<=2;i++) 
     { 
      System.out.println(p.poll()); 
     } 

    } 
} 
+10

PriorityQueueがバイナリヒープであり、contains()メソッドがO(n)で実行されていることを考慮すると、このコードよりも非効率なものはほとんど考えられませんでした。 –

関連する問題