java - LZW decoding miss the first code entry -
i followed rosetta java code implementation.
i tried lzw coding own dictionary , not ascii dictionary used. when try own dictioanry there problem decoding... result wrong, because each of decoded word don't view first 'a'
letter. result have 'abraca abrac abra'
, not 'braca brac bra'
i see problem in decode() method @ string act = "" + (char)(int)compressed.remove(0);
remove first 'a' letter. don't have ideas how can modify line... example if use string act = "";
instead of above line... coding wrong, or use command... don't know how can solve little problem... or maybe looking on bad way solution.
public class lzw { public static list<integer> encode(string uncompressed) { map<string,integer> dictionary = dictionaryinitstringint(); int dictsize = dictionary.size(); string act = ""; list<integer> result = new arraylist<integer>(); (char c : uncompressed.tochararray()) { string next = act + c; if (dictionary.containskey(next)) act = next; else { result.add(dictionary.get(act)); // add next dictionary. dictionary.put(next, dictsize++); act = "" + c; } } // output code act. if (!act.equals("")) result.add(dictionary.get(act)); return result; } public static string decode(list<integer> compressed) { map<integer,string> dictionary = dictionaryinitintstring(); int dictsize = dictionary.size(); string act = "" + (char)(int)compressed.remove(0); //string act = ""; string result = act; (int k : compressed) { string entry; if (dictionary.containskey(k)) entry = dictionary.get(k); else if (k == dictsize) entry = act + act.charat(0); else throw new illegalargumentexception("nincs ilyen kulcs: " + k); result += entry; dictionary.put(dictsize++, act + entry.charat(0)); act = entry; } return result; } public static map<string,integer> dictionaryinitstringint() { char[] characters = {'a','b','c','d','e','f','g','h','i','j', 'k','l','m','n', 'o','p','q','r','s','t','u','v','w','x','y','z',' ','!', '?','.',','}; int characterslength = characters.length; map<string,integer> dictionary = new hashmap<string,integer>(); (int = 0; < characterslength; i++) dictionary.put("" + characters[i], i); return dictionary; } public static map<integer,string> dictionaryinitintstring() { char[] characters = {'a','b','c','d','e','f','g','h','i','j', 'k','l','m','n', 'o','p','q','r','s','t','u','v','w','x','y','z',' ','!', '?','.',','}; int characterslength = characters.length; map<integer,string> dictionary = new hashmap<integer,string>(); (int = 0; < characterslength; i++) dictionary.put(i,"" + characters[i]); return dictionary; } public static void main(string[] args) { list<integer> compressed = encode("abraca abrac abra"); system.out.println(compressed); string decodeed = decode(compressed); // decodeed 'braca brac bra' system.out.println(decodeed); }
}
the rosetta example use
"" + (char) (int) compressed.remove(0);
because first 256 entries of dictionnary map 'char' values.
with custom dictionnary line should be:
string act = dictionary.get(compressed.remove(0));
Comments
Post a Comment