Dev Codex;

LZW in Java

Posted in Code by worldwise001 on February 25, 2009

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 Reply