3

我一直在阅读基于字典的压缩算法,包括 LZW 和 LZSS。然后,我想用 Java 实现 LZW 并开始研究它。我不是开发人员,所以我怀疑我的实现可能效率不高。你能看一下代码并告诉我在我的实现中有什么错误或效率低下吗?这是完整的代码。

public class LZW {

    public HashMap compdic, decompdic;
    String fileName = "walaloo.txt";
    short lastcode = 0, dlastcode = 0;

    LZW() {
        compdic = new HashMap<String, Integer>();
        decompdic = new HashMap<Integer, String>();
        createDictionary();
    }

    public void createDictionary() {
        try {
            short code;
            char ch;
            FileInputStream fis = new FileInputStream(fileName);
            InputStreamReader rdr = new InputStreamReader(fis, "utf-8");
            while ((code = (short) rdr.read()) != -1) {
                ch = (char) code;

                if (!compdic.containsKey(ch)) {
                    compdic.put("" + ch, code);
                    decompdic.put(code, "" + ch);
                    if (code > lastcode) {
                        lastcode = code;
                        dlastcode = code;
                    }
                }
            }
            fis.close();
        } catch (Exception ex) {
            Logger.getLogger(LZW.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void compressFile() {
        try {
            short code, codeword;
            char c;
            String s;

            System.out.print("Compressing...");
            FileInputStream fis = new FileInputStream(fileName);
            InputStreamReader rdr = new InputStreamReader(fis, "utf-8");
            FileOutputStream fos = new FileOutputStream(fileName + "1.lzw");
            ObjectOutputStream fout = new ObjectOutputStream(fos);

            s = (char) rdr.read() + "";
            while ((code = (short) rdr.read()) != -1) {
                c = (char) code;

                if (!compdic.containsKey(s + c)) {
                    codeword = Short.parseShort(compdic.get(s).toString());

                    fout.writeShort(codeword);
                    compdic.put(s + c, ++lastcode);
                    s = "" + c;
                } else {
                    s = s + c;
                }
            }

            codeword = Short.parseShort(compdic.get(s).toString());
            fout.writeShort(codeword);
            fout.writeShort(00);

            fout.close();
            fis.close();

            System.out.print("done");

        } catch (Exception ex) {
            Logger.getLogger(LZW.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void decompressFile() {
        short priorcode = -1, codeword = -1;
        char c;

        String priorstr, str;
        FileInputStream fis; 
        FileWriter fos; 
        ObjectInputStream fin;

        try {
            fis = new FileInputStream(fileName + "1.lzw");
            fos = new FileWriter(fileName + "2.txt");
            fin = new ObjectInputStream(fis);

            System.out.print("\nDecompressing...");
            priorcode = fin.readShort();
            fos.write(decompdic.get(priorcode).toString());
            while ((codeword = fin.readShort()) != -1) {
                if(codeword == 00)
                    break;

                priorstr = decompdic.get(priorcode).toString();

                if (decompdic.containsKey(codeword)) {
                    str = decompdic.get(codeword).toString();
                    fos.write(str);
                    decompdic.put(++dlastcode, priorstr + str.charAt(0));
                } else {
                    decompdic.put(++dlastcode, priorstr + priorstr.charAt(0));
                    fos.write(priorstr + priorstr.charAt(0));
                }

                priorcode = codeword;
            }

            fos.close();
            fis.close();
            System.out.print("done\n");

        } catch (Exception ex) {
            //Logger.getLogger(LZW.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("\n\nError: " + ex.getMessage());
            System.out.print(codeword + " " + priorcode + " " + decompdic.get(133) + " " + dlastcode);
        }
    }

    public static void main(String args[]) {
        LZW lzw = new LZW();
        lzw.compressFile();
        lzw.decompressFile();
    }
}
4

1 回答 1

1

您的字典大小为 32,767 项。(短)你不限制它的大小,不检查它。它适用于小文件。较大的文件会丢失数据。

于 2019-02-23T02:40:02.923 回答