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