LZW in Java
My CS330 prof was talking about LZW the other day. Since I had my laptop out, I figured I’d try to implement it (which I did, before class ended). It actually worked quite well (given his strings), and I think it will work for any string that contains “a” or “b” or both.
import java.util.HashMap;
public class Main {
public static void main(String[] args)
{
String str = "ababababbbaaaababbabababaaaabababbbbab";
String strEnc = LZWEncode(str);
System.out.println("Original length: " + str.length());
System.out.println("Length of encoding: " + strEnc.length());
System.out.println("Original: " + str);
System.out.println("Encoded: " + printCode(strEnc));
System.out.println("Decoded: " + LZWDecode(strEnc));
}
//result has ints turned into chars for ease of decoding
public static String LZWEncode(String str)
{
String result = "";
HashMap<String, Integer> h = new HashMap<String, Integer>();
h.put("a", 0);
h.put("b", 1);
int pos = 0;
int end = 1;
while (pos < str.length())
{
while (end < str.length() + 1 && h.containsKey(str.substring(pos, end))) end++;
if (end < str.length())
h.put(str.substring(pos,end), h.size());
result += (char)(h.get(str.substring(pos,end-1)).intValue());
pos = end-1;
}
return result;
}
public static String LZWDecode(String str)
{
String result = "";
HashMap<Integer, String> h = new HashMap<Integer, String>();
h.put(0, "a");
h.put(1, "b");
int pos = 0;
while (pos < str.length())
{
int key = (int)(str.charAt(pos));
if (h.containsKey(key))
{
result += h.get(key);
if (pos > 0)
{
int prevKey = (int)(str.charAt(pos-1));
h.put(h.size(), h.get(prevKey) + h.get(key).substring(0,1));
}
}
else
{
int prevKey = (int)(str.charAt(pos-1));
String newStr = h.get(prevKey) + h.get(prevKey).substring(0,1);
h.put(h.size(), newStr);
result += newStr;
}
pos++;
}
return result;
}
public static String printCode(String str)
{
String result = "";
for (int i = 0; i < str.length(); i++)
result += (int)str.charAt(i) + " ";
return result;
}
}
leave a comment