c#压缩短字符串和长字符串
本文关键字:字符串 压缩 | 更新日期: 2023-09-27 18:11:34
我想在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(在解码时发现无效数据)在解压方法中的行:邮政编码。读取(buffer, 0, buffer. length);你有什么建议?
您是否有特殊要求需要压缩5个字符?
否则你最终会一无所获地使用CPU和内存:在5个字符上获得空间的机会非常低(4%减少到4个字符,0.1%减少到3个字符,等等,如果字符串可以包含不同的大小写,标点符号,特殊字符等,甚至更少)
似乎有两个基本问题。一个是误差,一个是长度。
你所展示的代码似乎与这里相同:http://dotnet-snippets.com/dns/c-compress-and-decompress-strings-SID612.aspx
我不能证明这段代码中是否有任何错误,但对于我尝试的随机字符串分类(不同长度),它似乎工作得很好。给我们一个字符串的例子,这段代码失败,我们可以进一步研究。
至于长度,代码为开始的字符串长度增加了4个字节。所以压缩长度为5的字符串的几率是零。这还没有提到理论方面。鸽子洞原理本质上是基于这样一个事实,即长字符串可能比短字符串多。例如,只有10个一位数,但有100个两位数。因此,您不能将所有100个两位数字缩短为一位数字。如果你可以压缩任何字符串,你可以重复这个过程,把所有字符串压缩到一个比特。
您可以通过两种方式轻松地改进压缩。如果你知道你不会存储巨大的字符串,你可以减少存储的字符串长度,例如2字节而不是4字节。你可以存储一个比特来决定是否压缩字符串,如果压缩后的版本更大,你可以存储未压缩的字符串。它为压缩字符串增加了1位的开销,但如果您想要一致性,则可能更好。