【问题标题】:I'm getting some logical error in Huffman's encoding java我在 Huffman 的 Java 编码中遇到了一些逻辑错误
【发布时间】:2020-01-14 15:49:08
【问题描述】:

这里是代码...

public class Huffman_Coding {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        System.out.println("Enter a string to compress: ");
        String str = sc.nextLine();
        sc.close();
        HashString hs = new HashString();

        HashMap<Character, Integer> hm = hs.getStringHash(str);

        PriorityQueue<Node> pq = new PriorityQueue<Node>();
        for (char ch : hm.keySet()) {
            pq.add(new Node(null, null, hm.get(ch), ch));
        }
        System.out.println(pq);
        while (pq.size() != 1) {
            Node left = pq.poll();
            Node right = pq.poll();
            Node parent = new Node(left, right, left.freq + right.freq, '\0');
            pq.add(parent);
            System.out.println(pq);
        }
        Huffman_Tree ht = new Huffman_Tree();
        String ans = "";
        ht.inOrder(pq.poll(), ans);
    }
}

class Node implements Comparable<Node> {

    @Override
    public String toString() {
        return "Node [freq=" + freq + ", ch=" + ch + "]";
    }

    Node lptr;
    Node rptr;
    int freq;
    char ch;

    Node(Node lptr, Node rptr, int freq, char ch) {
        this.freq = freq;
        this.lptr = lptr;
        this.rptr = rptr;
        this.ch = ch;
    }

    public int compareTo(Node o) {

        int comparedvalue = Integer.compare(this.freq, o.freq);
        if (comparedvalue != 0)
            return comparedvalue;
        else
            return Integer.compare(this.ch, o.ch);
        }
    }

    boolean isLeaf() {
        return this.lptr == null && this.rptr == null;
    }
}

class Huffman_Tree {
    void inOrder(Node root, String code) {
        if (!root.isLeaf()) {
            inOrder(root.lptr, code + '0');
            inOrder(root.rptr, code + '1');

        } else
            System.out.println(root.ch + " : " + code);

    }
}

这里,对于输入字符串abccddeeee, 我得到了类似的东西:

[Node [freq=1, ch=a], Node [freq=1, ch=b], Node [freq=2, ch=c], Node [freq=2, ch=d], Node [freq=4, ch=e]]
[Node [freq=2, ch= ]]

我很困惑为什么在第二步中具有“d”的节点比“e”领先。这让我在最终编码中出错。为什么 compareTo 方法失败我无法理解。

getHashString 返回一个 Hash,其键为字符,值为频率。

【问题讨论】:

  • 能否提供HashString类的代码,以便重现您的问题?

标签: java huffman-code


【解决方案1】:

我无法弄清楚为什么 PriorityQueue 中的元素顺序不是 polling 元素和 adding 新“合成”元素之后的预期顺序,但是我认为您可以解决切换到TreeSet 的问题,就像我成功完成的那样

TreeSet<Node> pq = new TreeSet<Node>((n1, n2) -> n1.compareTo(n2)); // explicit but unnecessary comparator

并将每个 pq.poll() 调用更改为 pq.pollFirst()...

我希望这个解决方法可以帮助你!

编辑

正如您在official PriorityQueue documentation 中所读到的,* iterator() 方法中提供的迭代器不能保证以任何特定顺序遍历优先级队列的元素。如果需要有序遍历,可以考虑使用 Arrays.sort(pq.toArray()).*

这应该可以解释为什么toString() 方法调用以不同于预期优先级顺序的顺序显示队列元素...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-02
    • 2021-01-19
    • 2020-01-03
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多