LZW压缩算法

来源:互联网 发布:淘宝接单软件下载 编辑:程序博客网 时间:2024/05/02 02:44

压缩步骤:
1、初始化字典。使用链表初始化256个节点。节点存储编码、字符串、指针数据。编码为0-255(对应ASCII的单个字符)。如果被压缩对象中仅有有限几个字符时,可以自定义范围。例如对文本abaabbaab压缩,仅有a b两个字符,那么字典初始为{a=0,b=1}。

2、需要用到的几个变量String prefix,suffix,word;每次从文本中读取一个字符,赋值给suffix, prefix初始为空与suffix一起组成一个word。当word出现在词典中时,将word在词典中对应的编码赋值给prefix。当word不在词典中时,输出prefix对应的编码之后,将suffix赋值给prefix。并且将word加入到字典中去。

3、不停进行第二步直到读到最后一个字符,此时的编码输出并不完全。还差一个prefix的编码,输出它即可。

public static void code(String str) {        char[] c = str.toCharArray();        String prefix, suffix, word;        // 字典初始化        Node dictionary = null;        for(int i=0; i<256; i++) {            dictionary = addDictionary(dictionary, new Node(i, (char)i));        }        int index = 256;        int inDic;        prefix = "";        for (int i = 0; i < c.length; i++) {            suffix = String.valueOf(c[i]);            word = prefix + suffix;            // 是否在字典内            inDic = inDictionary(dictionary, word);            if (inDic != -1) {                prefix = String.valueOf(inDic);            } else { // 不在词典内                    dictionary = addDictionary(dictionary,                            new Node(index, word));                    index++;                }                // 输出prefix的编码                inDic = inDictionary(dictionary, prefix);                if(inDic == -1)                    System.out.print(prefix);                else                    System.out.print(inDic);                prefix = suffix;            }        }        // 输出最后一个prefix编码        inDic = inDictionary(dictionary, prefix);        if(inDic == -1)            System.out.print(prefix + "\n");        else            System.out.print(inDic + "\n");    }

解压步骤:
1、初始化字典链表。

2、需要用到变量prefix,suffix。每次取出一个编码字符,判断是否在字典内。当在字典内时,将该编码对应的字符串赋值给suffix并输出。并且将prefix+suffix.charAt(0)加入字典(需要保证prefix不为空的情况下,因为添加单个字符没意义,导致字典重复)。不在字典内,将prefix+prefix.charAt(0)赋值给suffix,并将suffix加入字典然后输出。

3、将suffix赋值给prefix。

4、重复2、3步骤,直到读取所有编码字符。

public static void decode(String str) {        char[] c = str.toCharArray();        // 字典初始化        Node dictionary = null;        for(int i=0; i<256; i++) {            dictionary = addDictionary(dictionary, new Node(i, (char)i));        }        String t;        String prefix = "", suffix = "";        int index = 256;        for (int i = 0; i < c.length; i++) {            t = inDictonary(dictionary, c[i] - '0');            if (t == null) {                suffix = prefix + prefix.charAt(0);                dictionary = addDictionary(dictionary, new Node(index, suffix));                index++;                System.out.print(suffix);            } else {                suffix = t;                System.out.print(suffix); // 如果该编码在字典内输出该字符                if (prefix.length() > 0) {                    dictionary = addDictionary(dictionary, new Node(index,                            prefix + suffix.charAt(0)));                    index++;                }            }            prefix = suffix;        }        System.out.println();    }

上面的代码依赖Node类和addDictionary()、inDictionary()方法。它们的定义如下:

public static String inDictonary(Node dictionary, int index) {        // 解码专用判断是否在字典中,根据编码串返回对应的串        while (dictionary != null) {            if (dictionary.code == index) { // 当编码相同                return dictionary.ch;            }            dictionary = dictionary.next;        }        return null;    }public static Node addDictionary(Node dictionary, Node node) {        node.next = dictionary;        dictionary = node;        return dictionary;    }public static int inDictionary(Node dictionary, String str) {    Node p = dictionary;    while (p != null) {        if (p.ch.equals(str)) {            return p.code;        }        p = p.next;    }    return -1;}public class Node {    public int code; // 对应编码0-255单个字符 256-65535双字节字符    public String ch; // 对应字符串    public Node next;    public Node(int c, String ch) {        code  = c;        this.ch = ch;        next = null;    }}

需要注意的是,仅针对ASCII字符的压缩。当字典过大时,每个编码的位数将不断增大,可以通过设置CLEAR END位来进行分段压缩。请参考:http://www.cqumzh.cn/uchome/space.php?uid=26081&do=blog&id=153720。下面这篇文章讲的比较易懂:http://ju.outofmemory.cn/entry/123990

0 0
原创粉丝点击