📄 compressor.java
字号:
package compress;
/**
* <p>Title: </p>
*
* <p>Description: </p>
*
* <p>Copyright: Copyright (c) 2007</p>
*
* <p>Company: </p>
*
* @author not attributable
* @version 1.0
*/
import java.io.*;
public class Compressor {
private static HuffNode[] chars = new HuffNode[511]; //存储字符及其出现频数
private static int top = 0; //记录chars中元素个数
private static HuffNode[] leafs; //存储叶子节点
public Compressor() {
}
private void scanFile(String fileName) { //扫描txt文件,根据字符及其对应的频率对cahars赋值 统计每个字符出现的次数
try {
BufferedReader fileInput =
new BufferedReader(new FileReader(fileName));
String line = null;
int sLength = 0;
char chuli;
do {
line = fileInput.readLine();
if (line != null) {
line=line+"\n";
sLength = line.length();
for (int i = 0; i < sLength; i++) {
chuli = line.charAt(i);
if (find(chuli) != null) { //判断chars中是否已有
(find(chuli)).jia1(); //频数加1
} else {
chars[top++] = new HuffNode(chuli, 1); //新建
}
}
}
} while (line != null);
fileInput.close();
} catch (IOException e) {
System.out.print(e.getMessage());
}
}
private HuffNode find(char c) {//判断c是否已在已有的数组中
int r = 0; //记录搜索位置
boolean isFound = false; //是否已经找到
HuffNode aNode = null;
while (r < top && !isFound) {
if (chars[r].getChar() == c) {
isFound = true; //已找到
aNode = chars[r];
} else {
r++;
}
}
return aNode;
}
private static void buildTree() {
for (int i = 0, m = top; i < 2 * top - 2; i += 2, m++) { //建树
sort(i, m - 1);//将chars数组按出现频率排序
chars[m] = new HuffNode(chars[i].weight() + chars[i + 1].weight()); //新建节点,节点的权重是它的两个字节点权重的和
chars[m].isLeaf = false; //表明不是叶子节点
chars[m].lChild = chars[i];
chars[m].rChild = chars[i + 1];
}
}
private static void sort(int start, int end) { //根据权重进行排序
for (int i = start + 1; i <= end; i++) {
for (int j = i;
(j > start) &&
(chars[j].weight() < chars[j - 1].weight());
j--) {
swap(j, j - 1); //进行换位
}
}
}
private static void swap(int i, int j) {
HuffNode temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
private void setLabel(HuffNode h) {
if (!h.isLeaf) {
h.lChild.label = "0"; //左子节点标识“0”,即编码中的“0”
h.lChild.path = h.path + h.lChild.label;
h.rChild.label = "1"; //右子节点标识“1”,即编码中的“1”
h.rChild.path = h.path + h.rChild.label;
setLabel(h.lChild); //递归
setLabel(h.rChild); //递归
}
}
private HuffNode[] pureLeafNode(HuffNode[] h) { //在chars中找出所有叶子节点并返回
HuffNode[] leafNode = new HuffNode[top];
for (int i = 0, j = 0; i < 2 * top - 1; i++) {
if (h[i].isLeaf) {
leafNode[j++] = h[i];
}
}
return leafNode;
}
private CodeNode[] toCodeNde(HuffNode[] hns){
CodeNode[] cns=new CodeNode[ hns.length];
for(int y=0;y<hns.length;y++){
cns[y]=new CodeNode(hns[y].getChar(),hns[y].path);
}
return cns;
}
CodeNode[] getNodes(String filename) {
HuffNode[] leaf;
CodeNode[]codeNodes;
scanFile(filename);
buildTree();
setLabel(chars[2 * top - 2]);
leaf = pureLeafNode(chars);
codeNodes=this.toCodeNde(leaf);
return codeNodes;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -