2012-01-03 103 views
0

我正在寻找可以压缩和解压缩Word文档的C#中的LZW压缩算法。我在谷歌搜索它,但它没有给我我需要的答案。任何人都可以帮助我获得它的代码,并让我了解如何在我的项目中真正实现LZW。LZW数据压缩

+3

你需要使用LZW而不是GZip的任何理由? – 2012-01-03 14:37:44

+1

可能[重复](http://stackoverflow.com/questions/6710014/lzw-compression-on-c-sharp-from-string) – 2012-01-03 14:42:30

+0

我会问同样的 - 具体使用LZW的原因是什么?您是否在与使用LZW的其他系统交互时尝试进行压缩/解压缩?如果是这样,则用户发布的实现可能与您的外部系统不兼容。请澄清这个问题。祝好, – 2012-01-03 14:47:51

回答

4

有一个实现here

LZW不关心它使用的文件类型。每个文件都被视为一个字节块。

+0

感谢您的帮助。 – Eric 2012-01-03 14:42:57

+1

这是一个奇怪而可怕的实现......它将值作为二进制字符串输出。 – Nyerguds 2017-07-29 14:06:32

1

下面是我在我的项目中使用的LZW的实施:

namespace LZW 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      List<int> compressed = Compress("string to be compressed"); 
      Console.WriteLine(string.Join(", ", compressed)); 
      string decompressed = Decompress(compressed); 
      Console.WriteLine(decompressed); 
     } 

     public static List<int> Compress(string uncompressed) 
     { 
      // build the dictionary 
      Dictionary<string, int> dictionary = new Dictionary<string, int>(); 
      for (int i = 0; i < 256; i++) 
       dictionary.Add(((char)i).ToString(), i); 

      string w = string.Empty; 
      List<int> compressed = new List<int>(); 

      foreach (char c in uncompressed) 
      { 
       string wc = w + c; 
       if (dictionary.ContainsKey(wc)) 
       { 
        w = wc; 
       } 
       else 
       { 
        // write w to output 
        compressed.Add(dictionary[w]); 
        // wc is a new sequence; add it to the dictionary 
        dictionary.Add(wc, dictionary.Count); 
        w = c.ToString(); 
       } 
      } 

      // write remaining output if necessary 
      if (!string.IsNullOrEmpty(w)) 
       compressed.Add(dictionary[w]); 

      return compressed; 
     } 

     public static string Decompress(List<int> compressed) 
     { 
      // build the dictionary 
      Dictionary<int, string> dictionary = new Dictionary<int, string>(); 
      for (int i = 0; i < 256; i++) 
       dictionary.Add(i, ((char)i).ToString()); 

      string w = dictionary[compressed[0]]; 
      compressed.RemoveAt(0); 
      StringBuilder decompressed = new StringBuilder(w); 

      foreach (int k in compressed) 
      { 
       string entry = null; 
       if (dictionary.ContainsKey(k)) 
        entry = dictionary[k]; 
       else if (k == dictionary.Count) 
        entry = w + w[0]; 

       decompressed.Append(entry); 

       // new sequence; add it to the dictionary 
       dictionary.Add(dictionary.Count, w + entry[0]); 

       w = entry; 
      } 

      return decompressed.ToString(); 
     } 
    } 
} 
+0

但是,为什么要使用列表而不是字节数组?另外,呃,它不仅仅是用于字符串...... – Nyerguds 2017-07-11 11:59:06

+0

它不仅仅是用于字符串。 ?你试图达到什么样的目的,你可以根据你的需求修改它,你也可以修改它来使用字节数组,而不是int,这只是一个示例。切记叠加流程仅供参考,并非编码服务:) – csharpcoder 2017-07-12 03:44:56

+0

LZW还用于非文本数据压缩。但是真的很难找到这样的例子:(至于我想要达到的目标,我正在研究在二进制文件存储中使用LZW的旧DOS游戏的修改工具。 – Nyerguds 2017-07-13 10:11:28