霍夫曼编码 - 处理unicode

时间:2012-11-01 08:10:12

标签: java unicode bytearray huffman-code

我在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字符将不止一个,但我不确定如何更改它。

有人可以给我一些指示吗?

1 个答案:

答案 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应该正确处理它。