LZW编码通过建立一个字符串表,用较短的代码来表示较长的字符串来实现压缩。 LZW压缩算法是Unisys的专利,有效期到2003年,所以相关算法大多也已过期。
本代码仅仅完成了LZW的编码与解码算法功能,相对网上找到的很多代码而言较为简(cai)单(bi),了解struct && 会递归即可,算是优点吧。
#include <stdio.h> #include <algorithm> #include <math.h> #include <iostream> #include <stdlib.h> #include <string.h> using namespace std; struct Node{ int pre; //前缀单词对应码字 char c; //当前字符 }KDA[65535]; int cnt,P,Q; char W,V; void Init(){ //前256个字典由对应ASCII码生成 for(int i = 0;i < 256; i ++){ KDA[i].pre = -1; KDA[i].c = i; } cnt = 256; P = -1; } void Out(int x){ //递归输出码字对应单词,首位另存用于建立字典 if(KDA[x].pre != -1){ Out(KDA[x].pre); } else { V = KDA[x].c; } printf("%c",KDA[x].c); } void Search(){ int flag = 0; for(int i = 0;i < cnt;i ++){ if(KDA[i].pre == P && KDA[i].c == W){//字典已存在则更新前缀对应码字 P = i; flag = 1; } } if(!flag){ //不存在则扩充字典,输出前缀对应码字并更新前缀单词 KDA[cnt].pre = P; KDA[cnt].c = W; printf("%03X ",P); P = (int)W; cnt ++; } } void Research(){ Out(Q); if(P != -1){ //如果前一位码字不为空,则将前一位对应单词作为前缀与本单词第一位合并作为新单词加入字典 KDA[cnt].pre = P; KDA[cnt].c = V; cnt ++; } } void Compress(){<span style="white-space:pre"> </span>//编码过程 Init(); freopen("LZWin.txt","r",stdin); freopen("LZWch.txt","w",stdout); while((W = getchar()) && W != EOF){ Search(); } printf("%03X\n",P); } void Decompress(){<span style="white-space:pre"> </span>//解码过程 Init(); freopen("LZWch.txt","r",stdin); freopen("LZWout.txt","w",stdout); while(scanf("%03X",&Q)!= EOF){ Research(); } } int main(){ Compress(); Decompress(); return 0; }
时间: 2024-11-16 09:02:51