简体   繁体   English

具有霍夫曼树的优先级队列

[英]Priority Queues with Huffman tree

i am trying to create a Huffman tree by reading in a file and counting the frequency of each letter space symbol etc. i'm using a Priorityqueue to queue the items from smallest to largest but when i insert them into the queue they dont queue correctly here is my code. 我试图通过读取文件并计算每个字母空格符号的频率等来创建一个霍夫曼树。我正在使用Priorityqueue将项目从最小到最大排队但是当我将它们插入队列时它们不能正确排队这是我的代码。 package huffman; 包霍夫曼;

import java.io.FileNotFoundException; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileReader; import java.util.ArrayList; import java.util.ArrayList; import java.util.PriorityQueue; import java.util.PriorityQueue; import java.util.Scanner; import java.util.Scanner;

public class Huffman { 公共课霍夫曼{

public ArrayList<Frequency> fileReader(String file)
{
    ArrayList<Frequency> al = new ArrayList<Frequency>();
    Scanner s;
    try {

        s = new Scanner(new FileReader(file)).useDelimiter("");
        while (s.hasNext())
        {
            boolean found = false;
            int i = 0;
            String temp = s.next();
            while(!found)
            {


                if(al.size() == i && !found)
                {
                    found = true;
                    al.add(new Frequency(temp, 1));
                }
                else if(temp.equals(al.get(i).getString()))
                {
                    int tempNum = al.get(i).getFreq() + 1;
                    al.get(i).setFreq(tempNum);
                    found = true;
                }
                i++;

            }



        }
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return al;
}
public void buildTree(ArrayList<Frequency> al)
{
    PriorityQueue<Frequency> pq = new PriorityQueue<Frequency>();
    for(int i = 0; i < al.size(); i++)
    {
        pq.add(al.get(i));          
    }
    while(pq.size() > 0)
    {
        System.out.println(pq.remove().getString());
    }
}
public void printFreq(ArrayList<Frequency> al)
{
    for(int i = 0; i < al.size(); i++)
    {
        System.out.println(al.get(i).getString() + "; " + al.get(i).getFreq());
    }
}

} }

in the buildTree() method is where im having the problem. 在buildTree()方法中我遇到了问题。 what im trying to do is queue Frequency objects which holds the letter/space/symbol and the frequency as an int the frequency class is this. 我试图做的是队列频率对象,其中包含字母/空格/符号,频率为int,频率等级为此。 public class Frequency implements Comparable { private String s; public class Frequency实现Comparable {private String s; private int n; 私人的

Frequency(String s, int n)
{
    this.s = s;
    this.n = n;
}
public String getString()
{
    return s;
}
public int getFreq()
{
    return n;
}
public void setFreq(int n)
{
    this.n = n;
}
@Override
public int compareTo(Object arg0) {
    // TODO Auto-generated method stub
    return 0;
}

} }

how can i get the priorityqueue to use the frequency number to queue them from smallest to biggest? 如何获得优先级使用频率编号将它们从最小到最大排队?

Actually you missed to implement the compareTo method to make your object effectively comparable. 实际上你错过了实现compareTo方法来使你的对象有效地进行比较。

The compareTo method, as documentation states, should compareTo方法,如文档所述,应该

return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. 返回负整数,零或正整数,因为此对象小于,等于或大于指定对象。

This means that in your case you should do something like: 这意味着在您的情况下,您应该执行以下操作:

public int compareTo(Object arg0)
{
  Frequency other = (Frequency)arg0;

  return n < other.n ? -1 : (n == other.n ? 0 : 1);
}

But mind that comparable has a generic type that is preferable: Comparable<T> so you can avoid the cast on arg0 to make it a Frequency object with static type safety too: 但是请注意,可比类型具有更优选的泛型类型: Comparable<T>因此您可以避免在arg0上进行arg0转换,使其成为具有静态类型安全性的Frequency对象:

class Frequency implements Comparable<Frequency> {   
  public int compareTo(Frequency f2) {
    // directly compare
  }
}

I think that "Auto-generated method stub" needs to be filled in with a real implementation of a "compareTo" so as to satisfy the requirements for something to be Comparable, which I assume the PriorityQueue is going to rely upon. 我认为“自动生成的方法存根”需要填充“compareTo”的实际实现,以满足可比较的东西的要求,我认为PriorityQueue将依赖它。 The implementation is probably going to be "n < arg0", with appropriate downcasting from Object. 实现可能是“n <arg0”,并从Object进行适当的向下转换。

A Priority Queue , just as a data structure, is based on the concept of an ordering - you use such a structure when you want to order elements in a certain way - which elements are more important than others, etc. 优先级队列 ,就像数据结构一样,基于排序的概念 - 当您想要以某种方式排序元素时,您使用这样的结构 - 哪些元素比其他元素更重要,等等。

In Java, ordering objects is usually done in one of two ways - your objects implement the Comparable interface, or you supply a Comparator<E> which knows how to order objects of type E . 在Java中,排序对象通常以两种方式之一完成 - 您的对象实现Comparable接口,或者您提供Comparator<E> ,它知道如何订购E类型的对象。

To determine which object is "more important" than another, the compareTo() method is invoked. 要确定哪个对象比另一个对象“更重要”,将调用compareTo()方法。 This method has a pretty simple contract: 这个方法有一个非常简单的合同:

Compares this object with the specified object for order. 将此对象与指定的对象进行比较以获得顺序。 Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. 返回负整数,零或正整数,因为此对象小于,等于或大于指定对象。

Your implementation of Frequency.compareTo() always returns 0 for the comparison. 您的Frequency.compareTo()始终返回0以进行比较。 Thus, you are specifying that all Frequency objects are equal to any other Frequency objects. 因此,您指定所有Frequency对象都等于任何其他Frequency对象。 This is clearly not what you want. 这显然不是你想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM