0

我想操纵一种算法来压缩 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); 你有什么建议?

4

2 回答 2

0

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

于 2013-04-30T11:34:35.600 回答
0

似乎有两个基本问题。一是误差,一是长度。

您显示的代码似乎与此处相同:http: //dotnet-snippets.com/dns/c-compress-and-decompress-strings-SID612.aspx

我无法证明这段代码中是否有任何错误,但它似乎适用于我尝试过的随机字符串分类(长度不同)。给我们一个该代码失败的字符串示例,我们可以进一步调查。

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

您可以通过两种方式轻松提高压缩率。如果你知道你不会存储巨大的字符串,你可以减少存储的字符串长度,例如 2 个字节而不是 4 个字节。你可以存储一些是否压缩字符串,如果压缩版更大。它为压缩字符串增加了 1 位开销,但如果您想要一致性可能会更好。

于 2013-04-30T12:10:43.637 回答