10 个版本
0.3.1 | 2024 年 3 月 19 日 |
---|---|
0.3.0 | 2024 年 2 月 24 日 |
0.2.5 | 2023 年 10 月 26 日 |
0.2.4 | 2023 年 5 月 24 日 |
0.1.0 | 2022 年 2 月 26 日 |
#81 in 压缩
664 每月下载量
在 8 个crate(2个直接) 中使用
115KB
1.5K SLoC
minimum_redundancy
是 Piotr Beling 编写的 Rust 库,用于使用二进制或非二进制最小冗余(霍夫曼)编码进行数据编码和解码。
该库运行速度快,内存消耗低,既可以用于构建(无需显式构建树)也可以用于存储编码字典(它只存储按频率排序的符号和规范霍夫曼树连续层级的非叶节点数量)。此外,该实现是通用的。它可以构建不仅限于二进制代码(通过二进制霍夫曼树获得),还可以构建任何阶数的树。
minimum_redundancy
的高效率得到了包含在(请在使用 minimum_redundancy
进行研究目的时引用此论文)中的基准测试的证实
- Piotr Beling, BSuccinct:专注于简洁数据结构的 Rust 库和程序,SoftwareX,第 26 卷,2024 年,101681,ISBN 2352-7110,https://doi.org/10.1016/j.softx.2024.101681.
该库使用了改进的霍夫曼算法,借鉴了以下论文中的想法
- A. Brodnik, S. Carlsson, 几乎就地解码霍夫曼码,1998
- A. Moffat, J. Katajainen, 就地计算最小冗余码。在:Akl S.G.,Dehne F.,Sack JR.,Santoro N.(编者)算法和数据结构。WADS 1995。计算机科学讲座笔记,第 955 卷。Springer,柏林,海德堡。 https://doi.org/10.1007/3-540-60220-8_79
示例
use minimum_redundancy::{Coding, Code, DecodingResult, BitsPerFragment};
use maplit::hashmap;
// Construct coding with 1 bit per fragment for values 'a', 'b', 'c',
// whose frequencies of occurrence are 100, 50, 10 times, respectively.
let huffman = Coding::from_frequencies(BitsPerFragment(1), hashmap!('a' => 100u32, 'b' => 50, 'c' => 10));
// We expected the following Huffman tree:
// / \
// /\ a
// bc
// and the following code assignment: a -> 1, b -> 00, c -> 01
assert_eq!(huffman.codes_for_values(), hashmap!(
'a' => Code{ content: 0b1, len: 1 },
'b' => Code{ content: 0b00, len: 2 },
'c' => Code{ content: 0b01, len: 2 }
));
// reverse codes encode the first levels of the tree on the least significant bits (e.g., c -> 10):
assert_eq!(huffman.reversed_codes_for_values(), hashmap!(
'a' => Code{ content: 0b1, len: 1 },
'b' => Code{ content: 0b00, len: 2 },
'c' => Code{ content: 0b10, len: 2 }
));
let mut decoder_for_a = huffman.decoder();
assert_eq!(decoder_for_a.consume(1), DecodingResult::Value(&'a'));
let mut decoder_for_b = huffman.decoder();
assert_eq!(decoder_for_b.consume(0), DecodingResult::Incomplete);
assert_eq!(decoder_for_b.consume(0), DecodingResult::Value(&'b'));
let mut decoder_for_c = huffman.decoder();
assert_eq!(decoder_for_c.consume(0), DecodingResult::Incomplete);
assert_eq!(decoder_for_c.consume(1), DecodingResult::Value(&'c'));
assert_eq!(huffman.total_fragments_count(), 5); // 1+2+2
assert_eq!(huffman.values.as_ref(), ['a', 'b', 'c']); // sorted by frequencies