【发布时间】:2015-09-26 07:55:56
【问题描述】:
我一直在阅读基于字典的压缩算法,包括 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();
}
}
【问题讨论】:
-
这段代码是否已经在工作,而您只是在寻求改进?那么您最好在codereview.stackexchange.com 上询问如果代码中有任何(已知)问题,您应该说明它们,以便我们知道您的问题是什么。
-
这看起来确实很适合代码审查,如果代码按预期工作,听起来确实如此。
-
我测试时代码运行良好。我没有发现任何问题。我最大的怀疑是我在创建压缩字典时使用了short。这意味着某些使用 Unicode 代码大于 32767 的非拉丁字母的语言无法被此处理。我还没有测试。
-
works fine when I tested你是怎么测试的?建议:1)压缩 2)重命名输入文件 3)尝试解压缩使用新实例,如果没有处理。预期结果:浩劫——你的解压似乎需要纯文本才能设置decompdic。
标签: java compression lzw