# 算法 5.5 霍夫曼压缩和LZW压缩

//Huffman
import edu.princeton.cs.algs4.*;
import edu.princeton.cs.algs4.MinPQ;

public class Huffman {
private final int R = 256;
private class Node implements  Comparable<Node>{
int fre;
char ch;
Node left, right;

public Node(char ch, int fre, Node left, Node right) {
this.fre = fre;
this.ch = ch;
this.left = left;
this.right = right;
}

@Override
public int compareTo(Node that) {
return this.fre = that.fre;
}

public boolean isLeaf() {
return left == null && right == null;
}
}

public void compress() {
char[] input = s.toCharArray(); // 将字符串转换为字符数组，便于后面的频率统计
int[] fre = new int[R];
for (int i = 0; i < input.length;i++) {
fre[input[i]]++;
}

Node root = buildTree(fre);
String[] st = buildCode(root);
writeTree(root);
BinaryStdOut.write(input.length);

for (int i = 0; i < input.length;i++) {
String code = st[input[i]];
for (int j = 0;j < code.length();j++) {
if (code.charAt(j) == '1') BinaryStdOut.write(true);
else BinaryStdOut.write(false);
}
}
BinaryStdOut.close();
}

}

private void writeTree(Node root) {
if (root.isLeaf()) {
BinaryStdOut.write(true);
BinaryStdOut.write(root.ch);
return;
}
BinaryStdOut.write(false);
writeTree(root.left);
writeTree(root.right);
}

private Node buildTree(int[] fre) {
MinPQ<Node> pq = new MinPQ<Node>();
for (char i = 0;i < R;i++) { // 用char而不是int的好处在于初始化Node时可以直接用i而不用转换类型
pq.insert(new Node(i, fre[i], null, null));
}

while (pq.size() > 1) { //不能用isempty函数，因为最后要剩一个
Node a = pq.delMin();
Node b = pq.delMin();
Node parent = new Node('\0', a.fre + b.fre, a, b);
pq.insert(parent);
}
return pq.delMin();
}

private String[] buildCode(Node root) {
String[] st = new String[R];
buildCode(st, root, "");
return st;
}

private void buildCode(String[] st, Node x, String s) {
if (x.isLeaf()) {
st[x.ch] = s;
return;
}
buildCode(st, x.left, s + '0');
buildCode(st, x.right, s + '1');
}

public void expand() {
for (int i = 0; i < N; i++) {
Node x = root;
while (!x.isLeaf()) {
else x = x.left;
}
BinaryStdOut.write(x.ch);
}
BinaryStdOut.close();
}

}

//LZW
import edu.princeton.cs.algs4.*;
public class LZW {
private static final int R = 256;
private static final int Width = 12;
private static final int Max = 4096;

public void compress() {
TST<Integer> st = new TST<>();
for (int i = 0;i < R;i++) {
st.put("" + (char) i, i);
}
int newCode = R + 1;

while (txt.length() > 0) {
String s = st.longestPrefixOf(txt);
BinaryStdOut.write(s, Width);

int t =s.length();
if (t < txt.length() && newCode < Max) {
st.put(txt.substring(0, t + 1), newCode++);
}
txt = txt.substring(t);
}
BinaryStdOut.write(R, Width);
BinaryStdOut.close();
}

public void expand() {
String[] st = new String[Max];
int i;

for (i = 0; i < R ;i++) {
st[i] = "" + (char) i;
}
st[i++] = " ";

String val = st[codeWord];
while (true) {
BinaryStdOut.write(val);
if (codeWord == R) break;
String s = st[codeWord];
if (i == codeWord) {
s = val + val.charAt(0);
}
if (i < Max) {
st[i++] = val + s.charAt(0);
}
val = s;
}
BinaryStdOut.close();
}
}


• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120