Java 在另一个类中实现Huffman类

Java 在另一个类中实现Huffman类,java,Java,我几乎有一个可以工作的哈夫曼算法,但我很难弄清楚如何实现它/或使它与代码类一起工作。我的方法generateHuffmanCode需要使用代码类。 我不知道我是否遗漏了什么,或者我只是使用了错误的方法 我的哈夫曼班 package code; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.PriorityQueue; import code.C

我几乎有一个可以工作的哈夫曼算法,但我很难弄清楚如何实现它/或使它与代码类一起工作。我的方法generateHuffmanCode需要使用代码类。 我不知道我是否遗漏了什么,或者我只是使用了错误的方法

我的哈夫曼班

package code;
  
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
  
import code.Code;
import application.TCode;
  
  
class Node{
    Character ch;
    Integer freq;
    Node left = null, right = null;
      
    Node(Character ch, Integer freq){
        this.ch = ch;
        this.freq = freq;
    }
      
    public Node (Character ch, Integer freq, Node left, Node right) {
        this.ch = ch;
        this.freq = freq;
        this.left = left;
        this.right = right;
    }
      
      
}
  
public class Huffman {
      
    public static void encode(Node root, String str, Map<Character, String> huffmanCode) {
        if (root == null) {
            return;
        }
        if(isLeaf(root)) {
            huffmanCode.put(root.ch, str.length() > 0 ? str : "1");
        }
        encode(root.left, str + '0', huffmanCode);
        encode(root.right, str + '1', huffmanCode);
    }
      
          
      
    public static int decode(Node root, int index, StringBuilder sb) {
        if(root == null) {
            return index;
        }
        index++;
          
        if(isLeaf(root)) {
            System.out.println(root.ch);
        }
        index++;
          
        root = (sb.charAt(index) == '0') ? root.left : root.right;
        index = decode(root, index, sb);
        return index;
    }
      
    public static boolean isLeaf(Node root) {
        return root.left == null && root.right == null;
    }
      
      
    public static void generateHuffmanCode(Code c) {
//      if(c == null || c.length() == 0) {
//          return;
//      }
        Map<Character, double> freq = new HashMap<>();   // why can't I use a double in Map<Character, double>??
        for(char s : probability.toCharArry()){
            freq.put(s, freq.getOrDefault(s, 0) + 1);
        }
          
        PriorityQueue<Node> pq;
        pq = new PriorityQueue<>(Comparator.comparingInt(l -> l.freq));
          
        for(var entry: freq.entrySet()) {
            pq.add(new Node(entry.getKey(), entry.getValue()));
        }
          
        while (pq.size() != 1) {
            Node left = pq.poll();
            Node right = pq.poll();
              
              
            int sum = left.freq + right.freq;
            pq.add(new Node(null, sum, left, right));
        }
          
        Node root = pq.peek();
          
        Map<Character, String> huffmanCode = new HashMap<>();
        encode(root, "", huffmanCode);
          
        System.out.println("Huffman Codes are: " + huffmanCode);
        System.out.println(probability);
          
        StringBuilder sb = new StringBuilder();
        for(char s : probability.toCharArray()) {
            sb.append(huffmanCode.get(s));
        }
        System.out.println("The endcoded String is: " + sb);
        System.out.println("The decoded String is: " );
          
        if (isLeaf(root)) {
            while (root.freq-- > 0) {
                System.out.println(root.ch);
            }
        } else {
            int index = -1;
            while(index < sb.length() - 1) {
                index = decode(root, index, sb);
            }
        }
    }
      
  
  
    public static void main(String[] args) {
          
  
        generateHuffmanCode(Code probability);
          
//      Code.CodeItem[] ci = {
//              new Code.CodeItem("A", 0.12),
//              new Code.CodeItem("B", 0.19),
//              new Code.CodeItem("C", 0.40),
//              new Code.CodeItem("D", 0.13),
//              new Code.CodeItem("E", 0.16)                
//      };
//      Code c = new Code(ci);
          
          
    }
  
  
}
包码;
导入java.util.Comparator;
导入java.util.HashMap;
导入java.util.Map;
导入java.util.PriorityQueue;
进口代码。代码;
导入application.TCode;
类节点{
字符ch;
整数频率;
节点左=空,右=空;
节点(字符ch,整数频率){
this.ch=ch;
this.freq=freq;
}
公共节点(字符ch、整数频率、左节点、右节点){
this.ch=ch;
this.freq=freq;
this.left=左;
这个。右=右;
}
}
公共级哈夫曼{
公共静态void编码(节点根、字符串str、映射huffmanCode){
if(root==null){
返回;
}
if(isLeaf(根)){
huffmanCode.put(root.ch,str.length()>0?str:“1”);
}
编码(root.left,str+'0',huffmanCode);
编码(root.right,str+'1',huffmanCode);
}
公共静态整数解码(节点根、整数索引、StringBuilder sb){
if(root==null){
收益指数;
}
索引++;
if(isLeaf(根)){
System.out.println(root.ch);
}
索引++;
root=(sb.charAt(index)='0')?root.left:root.right;
索引=解码(根、索引、sb);
收益指数;
}
公共静态布尔isLeaf(节点根){
返回root.left==null&&root.right==null;
}
公共静态无效生成uffmancode(代码c){
//如果(c==null | | c.length()==0){
//返回;
//      }
Map freq=new HashMap();//为什么我不能在Map中使用double??
for(char s:probability.toCharArry()){
freq.put(s,freq.getOrDefault(s,0)+1);
}
优先队列pq;
pq=新的优先级队列(比较器比较(l->l.freq));
for(变量条目:freq.entrySet()){
添加(新节点(entry.getKey(),entry.getValue());
}
而(pq.size()!=1){
节点左=pq.poll();
节点右侧=pq.poll();
int sum=left.freq+right.freq;
添加(新节点(空、和、左、右));
}
节点根=pq.peek();
Map huffmanCode=newhashmap();
编码(根“,”huffmanCode);
System.out.println(“哈夫曼代码为:“+huffmanCode”);
系统输出打印LN(概率);
StringBuilder sb=新的StringBuilder();
for(char s:probability.toCharArray()){
某人追加(huffmanCode.get);
}
System.out.println(“结束编码字符串为:“+sb”);
System.out.println(“解码字符串为:”);
if(isLeaf(根)){
while(root.freq->0){
System.out.println(root.ch);
}
}否则{
int指数=-1;
while(索引
还有我的代码类

package code;
 
public final class Code {
 
    private CodeItem[] item = null;
     
    public final static class CodeItem {
 
        private String symbol;
        private double probability;  // the sum of all probabilities must be approx. 1
        private String encoding;     // a string containing only '0' and '1'
         
        public CodeItem(String symbol, double probability, String encoding) {
            this.symbol = symbol.trim();
            this.probability = probability;
            this.encoding = encoding;
            if (!is01() || this.symbol == null || this.symbol.length() == 0 || this.probability < 0.0)
                throw new IllegalArgumentException();
        }
         
        public CodeItem(String symbol, double probability) {
            this(symbol, probability, null);
        }
         
        public String getSymbol() {
            return symbol;
        }
 
        public double getProbability() {
            return probability;
        }
 
        public String getEncoding() {
            return encoding;
        }
 
        public void setEncoding(String encoding) {
            this.encoding = encoding;
        }
 
        public boolean is01() {
             
            if (encoding == null || encoding.length() == 0)
                return true;
             
            for (int i = 0; i < encoding.length(); ++i)
                if ("01".indexOf(encoding.charAt(i)) < 0)
                    return false;
             
            return true;
        }
         
    }
     
    public Code(CodeItem[] codeItem) {
 
        if (codeItem == null || codeItem.length == 0)
            throw new IllegalArgumentException();
 
        double sum = 0.0;
        for (int i = 0; i < codeItem.length; ++i) {
            sum += codeItem[i].probability;
            if (codeItem[i].probability == 0.0)
                throw new IllegalArgumentException();
        }
        if (Math.abs(sum - 1.0) > 1e-10) 
            throw new IllegalArgumentException();
             
        item = new CodeItem[codeItem.length];
        for (int i = 0; i < codeItem.length; ++i)
            item[i] = codeItem[i];
         
    }
     
    public boolean is01() {
         
        for (int i = 0; i < item.length; ++i)
        if (!item[i].is01())
            return false;
         
        return true;
    }
 
     
    public double entropy() {
         
        double result = 0.0;
         
        for(int i = 0; i < item.length; ++i)
            result += item[i].probability * (-Math.log(item[i].probability) / Math.log(2.0));       
         
        return result;
    }
     
    public double averageWordLength() {
         
        double result = 0.0;
         
        for(int i = 0; i < item.length; ++i)
            result += item[i].encoding.length() * item[i].probability;      
         
        return result;
    }
     
    public boolean isPrefixCode() {
         
        for(int i = 1; i < item.length; ++i)
            for(int j = 0; j < i; ++j)
                if (item[i].encoding.startsWith(item[j].encoding) || item[j].encoding.startsWith(item[i].encoding))
                    return false;
        return true;
    }
     
    public int size() {
        return item.length;
    }
     
    public CodeItem getAt(int index) {
        return item[index];
    }
     
    public CodeItem getBySymbol(String symbol) {
 
        for (int i = 0; i < item.length; ++i) {
            if (item[i].symbol.equals(symbol))
                    return item[i];
        }
        return null;
    }
     
         
    public String toString() {
         
        String result = "";
         
        for(int i = 0; i < item.length; ++i) {
            result += item[i].symbol + " (" + item[i].probability +  ") ---> " + item[i].encoding + "\n";
        }
         
        return result.substring(0, result.length()-1);
    }
     
 
}
包码;
公共最终课程代码{
私有代码项[]项=null;
公共最终静态类代码项{
私有字符串符号;
私有双概率;//所有概率之和必须约为1
私有字符串编码;//仅包含“0”和“1”的字符串
公共代码项(字符串符号、双概率、字符串编码){
this.symbol=symbol.trim();
这个概率=概率;
this.encoding=编码;
如果(!is01()|| this.symbol==null | | this.symbol.length()==0 | | this.probability<0.0)
抛出新的IllegalArgumentException();
}
公共代码项(字符串符号,双概率){
这(符号、概率、空);
}
公共字符串getSymbol(){
返回符号;
}
公共双概率{
返回概率;
}
公共字符串getEncoding(){
返回编码;
}
公共空集合编码(字符串编码){
this.encoding=编码;
}
公共布尔值is01(){
if(encoding==null | | encoding.length()==0)
返回true;
对于(int i=0;i