LZW词典编码

LZW编码算法的步骤如下:
步骤1:将词典初始化为包含所有可能的单字符,当前前缀P初始化为空。
步骤2:当前字符C=字符流中的下一个字符。
步骤3:判断P+C是否在词典中
(1)如果“是”,则用C扩展P,即让P=P+C,返回到步骤2。
(2)如果“否”,则输出与当前前缀P相对应的码字W;将P+C添加到词典中;令P=C,并返回到步骤2

LZW解码算法如下:
步骤1:在开始译码时词典包含所有可能的前缀根。
步骤2:令CW:=码字流中的第一个码字。
步骤3:输出当前缀-符串string.CW到码字流。
步骤4:先前码字PW:=当前码字CW。
步骤5:当前码字CW:=码字流的下一个码字。
步骤6:判断当前缀-符串string.CW 是否在词典中。
(1)如果”是”,则把当前缀-符串string.CW输出到字符流。
当前前缀P:=先前缀-符串string.PW。
当前字符C:=当前前缀-符串string.CW的第一个字符。
把缀-符串P+C添加到词典。
(2)如果”否”,则当前前缀P:=先前缀-符串string.PW。
当前字符C:=当前缀-符串string.CW的第一个字符。
输出缀-符串P+C到字符流,然后把它添加到词典中。
步骤7:判断码字流中是否还有码字要译。
(1)如果”是”,就返回步骤4。
(2)如果”否”,结束。

将所给的.c文件中的内容,都复制到.cpp文件中。
编码

void LZWEncode( FILE *fp, BITFILE *bf)
{
 int character;
 int string_code;
 int index;
 unsigned long file_length;
 fseek( fp, 0, SEEK_END);//指针指向文件尾
 file_length = ftell( fp);//计算文件长度
 fseek( fp, 0, SEEK_SET);//指针重新指向文件开头
 BitsOutput( bf, file_length, 4*8);//写文件长度
 InitDictionary();//初始化词典
 string_code = -1;
 while( EOF!=(character=fgetc( fp)))//往后读一个字符
 {
  index = InDictionary( character, string_code);//判断是否在字典中
  if( 0<=index)// string+character in dictionary
  { 
   string_code = index;
  }
  else// string+character not in dictionary
  { 
   output( bf, string_code);//输出string_code
   if( MAX_CODE > next_code)// free space in dictionary
   { 
    // add string+character to dictionary
    AddToDictionary( character, string_code);
   }
   string_code = character;//string的编码
  }
 }
 output( bf, string_code);
}

解码

void LZWDecode( BITFILE *bf, FILE *fp)
{
 int character;
 int new_code, last_code;
 int phrase_length;
 unsigned long file_length;
 file_length = BitsInput( bf, 4*8);
 if( -1 == file_length) 
  file_length = 0;
  InitDictionary();
 last_code = -1;//同编码
 while( 0<file_length)//未没读到文件末尾
 {
  new_code = input( bf);
  if( new_code >= next_code)// 不在字典里,需要解码this is the case CSCSC( not in dict)
  { 
   d_stack[0] = character;
   phrase_length = DecodeString( 1, last_code);
  }
  else
  {
   phrase_length = DecodeString( 0, new_code);
  }
  character = d_stack[phrase_length-1];
  while( 0<phrase_length)
  {
   phrase_length --;
   fputc( d_stack[ phrase_length], fp);
   file_length--;
  }
  if( MAX_CODE>next_code)// add the new phrase to dictionary
  { 
   AddToDictionary( character, last_code);
  }
  last_code = new_code;
 }
}

bitio.c文件中涉及vs中fopen不安全,要求替换成fopen_s
解决方案:项目 =》属性 =》c/c++ =》预处理器=》点击预处理器定义,编辑,加入_CRT_SECURE_NO_WARNINGS,即可。
LZW词典编码_第1张图片
命令参数的设置
argv[1][0]是“E”或者“D”。E代表编码,D代表解码,argv[2]为输入文件,argv[3]为输出文件。
e
n
结果
LZW词典编码_第2张图片
2
各个文件格式压缩率比较
LZW词典编码_第3张图片

文本类文件基本能压缩,图片类文件基本不能压缩,视频、音频类文件也基本都能大幅压缩

压缩率的表格完成到最后的音频类后,网页崩了,内容消失,没有保存,所以表格略去,其他内容都重写了一遍

你可能感兴趣的:(LZW词典编码)