4

次のように PriorityQueue を使用してヒープを実装しようとしています。

PriorityQueue<Node> heap = new PriorityQueue<Node>();
Set<String> allWords = codebook.getAllWords();
for(String word : allWords)
{
    heap.add(new Node(word, codebook.getProbability(word)));
    System.out.println(heap.toString());
}

上記のメソッドを保持する同じクラス内のプライベート クラスとして Node を定義した場所。ノードは次のように定義されます。

private static class Node implements Comparable
{
    protected Node left;
    protected Node right;
    protected String name;
    protected double frequency;
    public Node(String n, double f)
    {
        name = n;
        frequency = f;
    }
    public Node(double f, Node l, Node r)
    {
        frequency = f;
        left = l;
        right = r;
    }

    @Override
    public int compareTo(Object arg0) 
    {
        Node other = (Node)(arg0);
        if(this.frequency < other.frequency)
        {
            System.out.println(name + " < " + other.name);
            return -1;
        }
        else if(this.frequency > other.frequency)
        {
            System.out.println(name + " > " + other.name);
            return 1;
        }
        System.out.println(name + " is equal to " + other.name);
        return 0;
    }

    public String toString()
    {return name;}
}

ただし、ノードを PriorityQueue に追加すると、それらは頻度順に並べられません。私のprintlnステートメントからの出力に基づいて、Node.compareTo()によって正しい値が返されます。たとえば、次のデータセットがあるとします。

  • 名前、頻度
  • 必要、3
  • 猫、1
  • ニート、2

私のコードは次のように生成します:
// need
[need]を追加します
// cat
cat < need
[cat, need]を追加します
// きちんとしたニートを追加し
ます > cat
[cat、need、neat] PriorityQueue
が [cat、きちんと、必要]
なぜこれが起こっているのかについてのヒントは?

4

2 に答える 2

3

の反復子PriorityQueueからの順序は定義されていません。呼び出すときの順序poll()は、コンパレータの順序にする必要があります。API仕様から、

iterator()このキュー内の要素の反復子を返します。イテレータは特定の順序で要素を返すわけではありません。

本当に必要なものがソートされたセットである場合は、SortedSetOR を使用してコレクションに入れ、 を使用しますCollections.sort()。ただし、本当に pqueue が必要な場合は、修正例を次に示します。

import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;


public class TestPriorityQueue 
{
  static Map<String,Double> codebook = new HashMap<String, Double>();
  static {
    codebook.put("need", 3.0);
    codebook.put("cat", 1.0);
    codebook.put("neat", 2.0);
  }

  public static void main(String[] args)
  {
    test();
  }

  public static void test() {
    PriorityQueue<Node> heap = new PriorityQueue<Node>();
    Set<String> allWords = codebook.keySet();
    for (String word : allWords) {
      heap.add(new Node(word, codebook.get(word)));
      System.out.println(heap.toString());
    }

    System.out.println("In order now:");
    while(!heap.isEmpty()) {
      System.out.println(heap.poll());
    }
  }

  private static class Node implements Comparable<Node>
  {
      protected Node left;
      protected Node right;
      protected String name;
      protected double frequency;
      public Node(String n, double f)
      {
          name = n;
          frequency = f;
      }
      public Node(double f, Node l, Node r)
      {
          frequency = f;
          left = l;
          right = r;
      }

      @Override
      public int compareTo(Node arg0) 
      {
          if(this.frequency < arg0.frequency)
          {
              System.out.println(name + " < " + arg0.name);
              return -1;
          }
          else if(this.frequency > arg0.frequency)
          {
              System.out.println(name + " > " + arg0.name);
              return 1;
          }
          System.out.println(name + " is equal to " + arg0.name);
          return 0;
      }

      public String toString()
      {return name;}
  }

}

与えます:

[need]
cat < need
[cat, need]
neat > cat
[cat, need, neat]
In order now:
neat < need
cat
neat
need
于 2011-03-29T02:40:57.540 に答える
2

PriorityQueues は「ジャスト イン タイム」ベースで機能します。内容を表示するだけでは、内容はソートされません。それらはヒープにあります(あなたが言及したので、あなたは知っていると思います。)とにかく、コンテンツを順番に取得するには、i poll() を使用して一度に 1 つずつアイテムを取り出す必要があります。

于 2011-03-29T02:43:43.163 に答える