我一直在阅读基于字典的压缩算法,包括 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();
}
}