我在java中实现了一个Huffman编码,它可以处理来自输入文件的字节数据。但是,它仅在压缩ascii时有效。我想扩展它以便它可以处理大于1个字节长的字符,但我不确定如何准确地执行此操作。
private static final int CHARS = 256;
private int [] getByteFrequency(File f) throws FileNotFoundException {
try {
FileInputStream fis = new FileInputStream(f);
byte [] bb = new byte[(int) f.length()];
int [] aa = new int[CHARS];
if(fis.read(bb) == bb.length) {
System.out.print("Uncompressed data: ");
for(int i = 0; i < bb.length; i++) {
System.out.print((char) bb[i]);
aa[bb[i]]++;
}
System.out.println();
}
return aa;
} catch (FileNotFoundException e) { throw new FileNotFoundException();
} catch (IOException e) { e.printStackTrace(); }
return null;
}
例如,这就是我用来获取文件中字符频率的内容,显然它只适用于单个字节。如果我给它一个unicode文件,我在aa[bb[i]]++;
得到一个ArrayIndexOutOfBoundsException,我通常是一个负数。我知道这是因为aa[bb[i]]++;
只查看一个字节,而unicode字符将不止一个,但我不确定如何更改它。
有人可以给我一些指示吗?
答案 0 :(得分:0)
尝试以下方法:
private static final int CHARS = 256;
private int [] getByteFrequency(File f) throws FileNotFoundException {
try {
FileInputStream fis = new FileInputStream(f);
byte [] bb = new byte[(int) f.length()];
int [] aa = new int[CHARS];
if(fis.read(bb) == bb.length) {
System.out.print("Uncompressed data: ");
for(int i = 0; i < bb.length; i++) {
System.out.print((char) bb[i]);
aa[((int)bb[i])&0xff]++;
}
System.out.println();
}
return aa;
} catch (FileNotFoundException e) { throw new FileNotFoundException();
} catch (IOException e) { e.printStackTrace(); }
return null;
}
如果我是正确的(我还没有测试过),你的问题是java中的字节是一个SIGNED值。转换为整数+将其屏蔽为0xff应该正确处理它。