这个项目的目的是为了让我 (jjrscott) 了解 LZW 的工作原理。在构建此项目时,我意识到最初描述的 LZW 算法包含两个不同的部分:
我可以使用 Swift 的 enum
来抽象掉预填充字符串表/字母表的需要,从而以更纯粹的形式揭示该算法。
来自 Rosetta Code
Lempel-Ziv-Welch (LZW) 算法提供无损数据压缩。
您可以在 Wikipedia 文章中阅读其完整描述。它曾被授予专利,但在 2004 年进入公共领域。
由于某种原因,所有演示都使用 TOBEORNOTTOBEORTOBEORNOT
作为输入字符串。 以下示例接受一个字符串并生成一个整数数组,就像原始演示一样。
import LZW
let original = "TOBEORNOTTOBEORTOBEORNOT"
let compressed = LZW.compress(original.utf8.map({$0}))
print("compressed: \(compressed)")
let encoded = compressed.map { unit in
switch unit {
case .element(let value):
return UInt(value)
case .index(let index):
return UInt(UInt8.max) + UInt(index)
}
}
print("encoded: \(encoded)")
输出
compressed: [.element(84), .element(79), .element(66), .element(69), .element(79),
.element(82), .element(78), .element(79), .element(84), .index(0),
.index(2), .index(4), .index(9), .index(3), .index(5), .index(7)]
encoded: [84, 79, 66, 69, 79, 82, 78, 79, 84, 256, 258, 260, 265, 259, 261, 263]
Initialize table to contain single-character strings
Read first input character K:
K → prefix string ω;
Step: Read next input character K
If no such K (input exhausted):
code(ω) → output;
EXIT.
If ωK exists in string table:
ωK → ω;
repeat Step.
else ωK not in string table:
code(ω) → output;
ωK → string table;
K → ω;
repeat Step.