-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathLZW.ts
More file actions
124 lines (99 loc) · 2.68 KB
/
LZW.ts
File metadata and controls
124 lines (99 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
*
* LZW压缩算法 - 字典压缩
*
* 问题:使用动态字典进行无损数据压缩
*
* 核心思想:
* - 动态构建编码字典
* - 查找最长匹配字符串
* - 输出字典索引
*
* 时间复杂度: O(n)
* 空间复杂度: O(n)
*/
const MAX_DICT_SIZE = 4096;
/*
*
* LZW压缩
*/
function lzwCompress(input: string): number[] {
const dictionary: { [key: string]: number } = {};
// 初始化字典(单字符)
for (let i = 0; i < 256; i++) {
dictionary[String.fromCharCode(i)] = i;
}
const compressed: number[] = [];
let current = "";
let dictSize = 256;
for (let i = 0; i < input.length; i++) {
const char = input[i];
const combined = current + char;
if (combined in dictionary) {
current = combined;
} else {
// 输出current的编码
compressed.push(dictionary[current]);
// 将combined加入字典
if (dictSize < MAX_DICT_SIZE) {
dictionary[combined] = dictSize++;
}
// 重置current为char
current = char;
}
}
// 输出最后一个编码
if (current !== "") {
compressed.push(dictionary[current]);
}
return compressed;
}
/*
*
* LZW解压
*/
function lzwDecompress(compressed: number[]): string {
const dictionary: { [key: number]: string } = {};
// 初始化字典(单字符)
for (let i = 0; i < 256; i++) {
dictionary[i] = String.fromCharCode(i);
}
let output = "";
let oldCode = compressed[0];
let oldString = dictionary[oldCode];
output += oldString;
let dictSize = 256;
for (let i = 1; i < compressed.length; i++) {
const newCode = compressed[i];
let stringVal: string;
if (!(newCode in dictionary)) {
// 特殊情况:new_code不在字典中
stringVal = oldString + oldString[0];
} else {
stringVal = dictionary[newCode];
}
output += stringVal;
// 将old_string + string[0]加入字典
if (dictSize < MAX_DICT_SIZE) {
dictionary[dictSize++] = oldString + stringVal[0];
}
oldString = stringVal;
}
return output;
}
/*
*
* 主函数
*/
function main(): void {
const input = "TOBEORNOTTOBEORTOBEORNOT";
console.log("=== LZW压缩算法 ===");
console.log(`原始文本: ${input}`);
const compressed = lzwCompress(input);
console.log(`压缩后编码: ${compressed}`);
const decompressed = lzwDecompress(compressed);
console.log(`解压后文本: ${decompressed}`);
console.log(`验证: ${input === decompressed}`);
}
// 运行测试
main();