c# - 链式哈希表和理解 Deflate

标签 c# algorithm compression

我目前正在尝试创建自定义 Deflate在 C# 中实现。

我目前正在尝试实现“模式搜索”部分,其中我有(最多)32k 的数据,并且正在尝试为我的输入搜索最长的可能模式。

RFC 1951定义 Deflate 的内容讲述了该过程:

The compressor uses a chained hash table to find duplicated strings, using a hash function that operates on 3-byte sequences. At any given point during compression, let XYZ be the next 3 input bytes to be examined (not necessarily all different, of course). First, the compressor examines the hash chain for XYZ. If the chain is empty, the compressor simply writes out X as a literal byte and advances one byte in the input. If the hash chain is not empty, indicating that the sequence XYZ (or, if we are unlucky, some other 3 bytes with the same hash function value) has occurred recently, the compressor compares all strings on the XYZ hash chain with the actual input data sequence starting at the current point, and selects the longest match.

我确实知道什么是哈希函数,也知道什么是哈希表。但是什么是“链式哈希表”以及如何设计这样的结构才能高效(在 C# 中)处理大量数据?不幸的是,我不明白 RFC 中描述的结构是如何工作的。

我可以选择什么样的哈希函数(什么才有意义)?

提前谢谢您!

最佳答案

链式哈希表是一个存储您放入其中的每个项目的哈希表,即使 2 个项目的键哈希为相同的值,或者即使 2 个项目具有完全相同的键。

DEFLATE 实现需要以不特定的顺序存储一堆(键、数据)项,并快速查找具有该键的所有项的列表。 在本例中, key 是未压缩明文的 3 个连续字节,而数据是指向该 3 字节子字符串在明文中出现位置的某种指针或偏移量。

许多哈希表/字典实现都存储每个项目的键和数据。 没有必要将 key 存储在表中以进行 DEFLATE,但除了在压缩期间使用稍微多一点的内存之外,它不会造成任何损害。

一些哈希表/字典实现(例如 C++ STL unordered_map)坚持认为它们存储的每个(键、数据)项都必须具有唯一的键。当您尝试存储与表中已有的某些旧项目具有相同键的另一个(键、数据)项目时,这些实现会删除旧项目并将其替换为新项目。 这确实会造成伤害 - 如果您不小心使用了 C++ STL unordered_map 或类似的实现,您的压缩文件将比使用更合适的库(例如 C++)时更大STL hash_multimap。 这种错误可能很难检测到,因为任何标准 DEFLATE 压缩器都可以将生成的(不必要的大)压缩文件正确解压缩为与原始文件逐位相同的文件。 DEFLATE 和其他压缩算法的一些实现故意使用这样的实现,故意牺牲压缩文件大小以获得压缩速度。

正如 Nick Johnson 所说,标准“哈希表”或“字典”实现中使用的默认哈希函数可能已经足够了。

http://en.wikipedia.org/wiki/Hashtable#Separate_chaining

关于c# - 链式哈希表和理解 Deflate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6831399/

相关文章:

c# - HttpModule 和 Global.aspx 之间的性能差异是什么?

python - 查找类似功能/产品组合的模式(最好在 python 中)

algorithm - 实现将按距离排序的地点返回给当前用户的服务操作的最佳方式是什么?

hadoop - 如何将自定义 hadoop native 编解码器编译为 libhadoop.so?

android - 压缩图像和调整图像大小有什么区别?安卓

c# - 如何检索启动自动化测试的工作项的 ID

c# - 尝试通过 ID 获取消息时出现 Microsoft.Graph.Models.ODataErrors.ODataError 错误。 Microsoft Graph GraphServiceClient

ffmpeg - 同一帧图像,通过相同的算法或库,两次压缩后图像相同与否

c# - 将命令行参数传递给单一服务

javascript - 我的代码没有正确比较两个不同的字符串