Algorithm LZW解压算法

Algorithm LZW解压算法,algorithm,compression,lzw,Algorithm,Compression,Lzw,我正在为一个必须实现LZW压缩/解压缩的作业编写一个程序。 为此,我使用以下算法: -压缩 w = NIL; while ( read a character k ) { if wk exists in the dictionary w = wk; else add wk to the dictionary; output the code for w; w = k;

我正在为一个必须实现LZW压缩/解压缩的作业编写一个程序。 为此,我使用以下算法:

-压缩

w = NIL;
   while ( read a character k )
       {
         if wk exists in the dictionary
         w = wk;
         else
         add wk to the dictionary;
         output the code for w;
         w = k;
       }
read a character k;
   output k;
   w = k;
   while ( read a character k )    
  /* k could be a character or a code. */
        {
         entry = dictionary entry for k;
         output entry;
         add w + entry[0] to dictionary;
         w = entry;
        }
read a character k;
   output k;
   w = k;
   while ( read a character k )    
  /* k could be a character or a code. */
        {
         if k exists in the dictionary
         entry = dictionary entry for k;
         output entry;
         add w + entry[0] to dictionary;
         w = entry;
         else
         output entry = w + firstCharacterOf(w);
         add entry to dictionary;
         w = entry;
        }
-减压

w = NIL;
   while ( read a character k )
       {
         if wk exists in the dictionary
         w = wk;
         else
         add wk to the dictionary;
         output the code for w;
         w = k;
       }
read a character k;
   output k;
   w = k;
   while ( read a character k )    
  /* k could be a character or a code. */
        {
         entry = dictionary entry for k;
         output entry;
         add w + entry[0] to dictionary;
         w = entry;
        }
read a character k;
   output k;
   w = k;
   while ( read a character k )    
  /* k could be a character or a code. */
        {
         if k exists in the dictionary
         entry = dictionary entry for k;
         output entry;
         add w + entry[0] to dictionary;
         w = entry;
         else
         output entry = w + firstCharacterOf(w);
         add entry to dictionary;
         w = entry;
        }
对于压缩阶段,我只是输出表示 字典条目,也是起始字典由ascii字符(0-255)组成。 但是当我到了解压阶段,我得到了这个错误 例如,如果我压缩一个只包含“booop”的文本文件 它将通过以下步骤生成输出文件:

w       k       Dictionary          Output

-       b       -                   -
b       o       bo (256)            98 (b)
o       o       oo (257)            111 (o)
o       o       -                   -
oo      p       oop (258)           257 (oo)
p       -       -                   112 (p)
output.txt: 98 111 257 112

然后当我来解压文件的时候

w       k          entry        output       Dictionary
        98 (b)                  b   
b       111 (o)    o            o             bo (256)
o       257 (error)
257(oo)尚未添加。有人能看出我哪里出了问题吗?因为我 难倒了。算法错了吗?

你是否陷入这种情况

如果解码器接收到尚未在其字典中的代码Z,会发生什么情况?因为解码器总是在编码器后面只有一个代码,所以只有当编码器刚刚生成Z时,Z才能在编码器的字典中,当发出之前的代码X表示χ时。因此Z编码一些ω,即χ+?,解码器可以确定未知字符,如下所示:

1) The decoder sees X and then Z.
2) It knows X codes the sequence χ and Z codes some unknown sequence ω.
3) It knows the encoder just added Z to code χ + some unknown character,
4) and it knows that the unknown character is the first letter z of ω.
5) But the first letter of ω (= χ + ?) must then also be the first letter of χ.
6) So ω must be χ + x, where x is the first letter of χ.
7) So the decoder figures out what Z codes even though it's not in the table,
8) and upon receiving Z, the decoder decodes it as χ + x, and adds χ + x to the table as the value of Z.
每当编码器遇到形式为cScSc的输入时,就会出现这种情况,其中c是单个字符,S是字符串,cS已经在字典中,但cSc不是。编码器发出cS的代码,将cSc的新代码放入字典中。接下来,它在输入中看到cSc(从cScSc的第二个c开始),并发出刚刚插入的新代码。上面的参数表明,每当解码器接收到不在其字典中的代码时,情况必须如下所示

尽管形式cScSc的输入看起来不太可能,但当输入流具有显著重复的特征时,这种模式相当常见。特别是,单个字符的长字符串(在LZW常用的图像类型中)会反复生成这种类型的模式



对于这个特定的例子,维基百科的东西适合,你有X+?其中X是(o),Z到目前为止是未知的,因此第一个字母是X,表示(oo)将(oo)添加到表中作为257。我正在继续我在维基百科上读到的内容,如果这不是解决方案,请告诉我们结果如何。

您的压缩部分正确且完整,但解压缩部分不完整。仅当代码在字典中时才包含大小写。由于解压过程总是比压缩过程晚一步,因此解码器可能会发现字典中没有的代码。但由于它只落后一步,它可以计算出编码过程接下来将添加什么,并正确输出解码字符串,然后将其添加到字典中。要像这样继续解压缩过程,请执行以下操作:

-减压

w = NIL;
   while ( read a character k )
       {
         if wk exists in the dictionary
         w = wk;
         else
         add wk to the dictionary;
         output the code for w;
         w = k;
       }
read a character k;
   output k;
   w = k;
   while ( read a character k )    
  /* k could be a character or a code. */
        {
         entry = dictionary entry for k;
         output entry;
         add w + entry[0] to dictionary;
         w = entry;
        }
read a character k;
   output k;
   w = k;
   while ( read a character k )    
  /* k could be a character or a code. */
        {
         if k exists in the dictionary
         entry = dictionary entry for k;
         output entry;
         add w + entry[0] to dictionary;
         w = entry;
         else
         output entry = w + firstCharacterOf(w);
         add entry to dictionary;
         w = entry;
        }
然后,当你来解压文件,看到257,你会发现它不在字典里。但是你知道前面的条目是‘o’,它的第一个字符也是‘o’,把它们放在一起,你会得到‘oo’。现在输出oo并将其添加到字典中。下一步,你得到代码112,并确保你知道它的p。完成了

w       k          entry        output       Dictionary
        98 (b)                  b   
b       111 (o)    o            o             bo (256)
o       257 (oo)                oo            oo(257)
oo      112(p)                  p

更多信息,请参见Steve Blackstock的解释。Java图像库GIF编码器和解码器所基于的实际解码器和编码器实现的流程图

你能给我们看真实的代码吗,因为伪代码总是模棱两可的。问题解决了吗?是的,我实现了你对算法所做的更改,它工作了。谢谢,我现在对它的实际工作有了更好的理解。