3

我有一个用于在 TStringList 中存储许多字符串的应用程序。这些字符串将在很大程度上彼此相似,并且我突然想到可以即时压缩它们 - 即根据唯一文本片段加上对先前存储片段的引用来存储给定字符串。StringLists,例如完全限定的路径和文件名列表,应该能够被大大压缩。

有谁知道实现此功能的 TStringlist 后代 - 即提供对未压缩字符串的读写访问权限,但将它们存储在内部压缩,以便 TStringList.SaveToFile 生成压缩文件?

虽然您可以通过在每次访问之前解压缩整个字符串列表并在之后重新压缩它来实现这一点,但这会不必要地慢。我追求的是对增量操作和随机“搜索”和读取有效的东西。

TIA 罗斯

4

4 回答 4

2

我认为没有任何免费可用的实现(无论如何我都不知道,尽管我已经用商业代码编写了至少 3 个类似的结构),所以你必须自己动手。

Marcelo 关于按顺序添加项目的评论非常相关,因为我想您可能希望在添加时压缩数据 - 快速访问已经与正在添加的条目相似的条目,比必须提供更好的性能在整个集合中查找“最佳拟合条目”(相似性压缩所需)。

您可能想要阅读的另一件事是“绳索”——一种在概念上与字符串不同的类型,我已经在不久前向 Marco Cantu 建议过。以每个 'twine' 的下一个指针为代价(因为没有更好的词),您可以连接字符串的各个部分,而不会保留任何重复的数据。主要问题是如何检索可以组合成新“绳索”的部分,代表您的原始字符串。解决该问题后,您可以随时将数据重建为字符串,同时仍具有紧凑的存储空间。

如果您不想走“绳索”路线,您还可以尝试一种称为“前缀缩减”的方法,这是一种简单的压缩形式 - 只需从每个字符串开始,使用前一个字符串的索引和字符数这应该被视为新字符串的前缀。请注意,您不应其递归太远,否则访问速度将受到很大影响。在一个简单的实现中,我mod 16在索引上做了一个,以建立开始减少前缀的条目,这平均为我节省了大约 40% 的内存(当然,这个数字完全取决于数据)。

于 2010-09-13T13:59:52.660 回答
0

您可以尝试将 Delphi 或 COM API 包装在Judy 数组周围。JudySL 类型可以解决问题,并且具有相当简单的界面。

编辑:我假设您正在存储唯一的字符串并希望(或乐于)按字典顺序存储它们。如果这些约束不可接受,那么 Judy 数组不适合您。请注意,如果您不对字符串进行排序,任何压缩系统都会受到影响。

于 2010-07-13T13:07:07.560 回答
0

我不认为你真的想压缩内存中的 TStrings 项目,因为它非常低效。我建议您查看 Zlib 单元中的 TStream 实现。只需在加载时将常规流包装到 TDecompressionStream 中,在保存时将 TCompressionStream 包装(您甚至可以在那里发出 gzip 标头)。提示:您需要覆盖 LoadFromStream/SaveToStream 而不是 LoadFromFile/SaveToFile

于 2010-11-13T02:37:09.287 回答
0

我想您希望列表具有一般的灵活性(包括删除操作),在这种情况下,我不知道任何开箱即用的解决方案,但我建议使用以下两种方法之一:

  • 您将字符串拆分为单词并保持分离的增长字典以引用单词并在内部保存索引列表

  • 您实现了一些与 Delphi 中可用的 zlib 流相关的东西,但由例如可以包含 10-100 个字符串的块操作。在这种情况下,您仍然需要重新压缩/压缩整个块,但您支付的“价格”较低。

于 2010-07-13T14:47:59.233 回答