我想操纵一个算法来压缩c#中的长字符串和短字符串,我尝试过的所有算法都能够压缩长字符串而不是短字符串(大约5个字符)。代码是:
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(buffer,0,buffer.Length); 你有什么建议吗?
答案 0 :(得分:0)
您是否有特殊要求需要压缩5个字符? 否则你最终将无需使用CPU和内存:获得5个字符空间的机会非常低(4%减少到4个字符,0.1%减少到3个字符等等,如果字符串可以更少包含不同的大小写,标点符号,特殊字符等。)
答案 1 :(得分:0)
似乎有两个基本问题。一个是错误,一个是长度。
您展示的代码似乎与此处相同: http://dotnet-snippets.com/dns/c-compress-and-decompress-strings-SID612.aspx
我无法证明此代码中是否存在任何错误,但它似乎适用于我尝试过的随机分类字符串(长度各异)。给我们一个代码失败的字符串示例,我们可以进一步调查。
至于长度,代码为字符串长度添加4个字节只是为了开始。所以你压缩长度为5的字符串的几率是zilch。这甚至没有提到理论方面。鸽笼原理基本上是基于这样一个事实,即长串比短串更可能。例如,只有10个一位数字,但有100个两位数字。因此,您无法将所有100个两位数字缩短为一位数。此外,如果您可以压缩任何字符串,您可以重复该过程并将所有字符串压缩到一位。
您可以通过两种方式轻松改善压缩效果。如果你知道你不会存储大字符串,你可以减少存储的字符串长度,例如你可以存储一下是否压缩字符串,如果压缩版本更大则存储未解压缩。它为压缩字符串增加了1位开销,但如果你想要一致性可能会更好。