2013-04-30 109 views
0

我想操纵一个算法来压缩在C#中多空双方的字符串,所有我曾试图算法能够压缩长字符串,但也不短(约5个字符)。的代码是:C#压缩短期和长期的字符串

using System; 
using System.Collections.Generic; 
using System.IO.Compression; 
using System.IO; 
using System.Collections; 
using System.Text; 

namespace CompressString { 
internal static class StringCompressor 
{ 
    /// <summary> 
    /// Compresses the string. 
    /// </summary> 
    /// <param name="text">The text.</param> 
    /// <returns>compressed string</returns> 
    public static string CompressString(string text) 
    { 
     byte[] buffer = Encoding.Default.GetBytes(text); 
     MemoryStream ms = new MemoryStream(); 
     using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true)) 
     { 
      zip.Write(buffer, 0, buffer.Length); 
     } 
     ms.Position = 0; 
     byte[] compressed = new byte[ms.Length]; 
     ms.Read(compressed, 0, compressed.Length); 
     byte[] gzBuffer = new byte[compressed.Length + 4]; 
     System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length); 
     System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4); 
     return Encoding.Default.GetString(gzBuffer); 
    } 

    /// <summary> 
    /// Decompresses the string. 
    /// </summary> 
    /// <param name="compressedText">The compressed text</param> 
    /// <returns>uncompressed string</returns> 
    public static string DecompressString(string compressedText) 
    { 
     byte[] gzBuffer = Encoding.Default.GetBytes(compressedText); 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      int msgLength = BitConverter.ToInt32(gzBuffer, 0); 
      ms.Write(gzBuffer, 4, gzBuffer.Length - 4); 
      byte[] buffer = new byte[msgLength]; 
      ms.Position = 0; 
      using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress)) 
      { 
       zip.Read(buffer, 0, buffer.Length); 
      } 
      return Encoding.Default.GetString(buffer); 
     } 
    } 
}} 

我InvalidDataException在管线中解压缩方法(在解码发现无效的数据): zip.Read(缓冲液,0,buffer.Length); 你有什么建议?

+0

你应该发布一些代码,你已经尝试了什么,或者至少扩展了你的问题。请参阅http://stackoverflow.com/faq – 2013-04-30 10:47:27

+0

压缩可以*从不*保证将所有内容缩短......并且压缩非常少量的数据非常少见。 – 2013-04-30 10:48:38

+0

例如:如果你有一个像'aaaaa'这样的字符串,那么你可以将它缩短为'5a'。但是如果你有像'afgdc'这样的字符串,那么没有真正有意义的方法来缩短它的算法。你可以创建一个字典并说'1 =“afgdc”',然后只提交'1',但另一方需要知道'1'代表什么,所以你还需要提交字典,你还没有获得任何东西。 – Corak 2013-04-30 11:08:45

回答

0

你有需要压缩5个字符有特殊要求?
否则你会最终使用的CPU和内存白白:获得5个字符的空间都非常低(4%减少到4个字符的机会,0.1%减少到3个字符等,甚至更少,如果字符串可以包含不同的情况下,标点符号,特殊字符等)

+0

是的,我有。所以你建议不要压缩这样短的刺痛,但是如果我的字符串有1200个字符的限制,我应该从哪个长度开始压缩? – user1477701 2013-04-30 12:01:40

+0

对不起,我没有回答你:你应该自己测试。制作一个产生不同长度随机字符串的小代码,然后压缩并比较结果。每个长度做100次(即5,10,20等),并将结果写入csv,以便您可以在Excel中打开并绘制图形。它应该给你一个答案。 – Fabske 2013-04-30 14:51:03

0

看来,有两个基本的问题。一个是错误,一个是长度。

还有你的代码似乎是一样的位置: http://dotnet-snippets.com/dns/c-compress-and-decompress-strings-SID612.aspx

我不能attestify是否有此代码的任何错误,但它似乎对字符串进行随机搭配做工精细我尝试过(不同长度)。给我们一个这个代码失败的字符串的例子,我们可以进一步调查。

至于长度,代码被加入4个字节的字符串长度正好开始。所以你压缩一个长度为5的字符串的几率是zilch。这甚至没有提到理论方面。鸽子的原理基本上是基于这样一个事实,即比短弦有更多可能的长弦。例如,只有10个一位数字,而是100个两位数字。因此,您无法将所有100个两位数缩减到一位数。此外,如果您可以压缩任何字符串,则可以重复该过程并将所有字符串压缩到一位。

你可以轻松地提高您的压缩一点两种方式。如果你知道你不会储存巨大的琴弦,你可以减少储存的琴弦长度,例如到2个字节,而不是4个。你可以存储一点,不管你是否压缩字符串,如果压缩版本较大,可以将它存储为未压缩的。它为压缩的字符串增加了1位的开销,但如果你想保持一致性,可能会更好。

+0

例如,这段代码在压缩时失败'headache'这个词 – user1477701 2013-04-30 12:23:02

+0

其实我是非常新手的压缩算法,所以我会非常感谢您的帮助。 – user1477701 2013-04-30 12:26:33

+0

嗯,相同的代码为我工作“头痛”。你可以显示你调用这个类的代码吗?错误可能在那里。 你能解释一下你想要压缩的东西吗?他们只是文字吗?句子? GZip很棒,但不是解决所有问题的方法。例如,如果我们知道只有字母,数字或标点符号,我们可以保证压缩它。 – 2013-05-01 09:37:20