-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathLZW.java
More file actions
129 lines (103 loc) · 3.35 KB
/
LZW.java
File metadata and controls
129 lines (103 loc) · 3.35 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
125
126
127
128
129
/*
*
* LZW压缩算法 - 字典压缩
*
* 问题:使用动态字典进行无损数据压缩
*
* 核心思想:
* - 动态构建编码字典
* - 查找最长匹配字符串
* - 输出字典索引
*
* 时间复杂度: O(n)
* 空间复杂度: O(n)
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LZW {
private static final int MAX_DICT_SIZE = 4096;
/*
*
* LZW压缩
*/
public static List<Integer> compress(String input) {
Map<String, Integer> dictionary = new HashMap<>();
// 初始化字典(单字符)
for (int i = 0; i < 256; i++) {
dictionary.put(String.valueOf((char) i), i);
}
List<Integer> compressed = new ArrayList<>();
String current = "";
int dictSize = 256;
for (int i = 0; i < input.length(); i++) {
char nextChar = input.charAt(i);
String combined = current + nextChar;
if (dictionary.containsKey(combined)) {
current = combined;
} else {
// 输出current的编码
compressed.add(dictionary.get(current));
// 将combined加入字典
if (dictSize < MAX_DICT_SIZE) {
dictionary.put(combined, dictSize++);
}
// 重置current为next_char
current = String.valueOf(nextChar);
}
}
// 输出最后一个编码
if (!current.isEmpty()) {
compressed.add(dictionary.get(current));
}
return compressed;
}
/*
*
* LZW解压
*/
public static String decompress(List<Integer> compressed) {
Map<Integer, String> dictionary = new HashMap<>();
// 初始化字典(单字符)
for (int i = 0; i < 256; i++) {
dictionary.put(i, String.valueOf((char) i));
}
StringBuilder output = new StringBuilder();
int oldCode = compressed.get(0);
String oldString = dictionary.get(oldCode);
output.append(oldString);
int dictSize = 256;
for (int i = 1; i < compressed.size(); i++) {
int newCode = compressed.get(i);
String string;
if (!dictionary.containsKey(newCode)) {
// 特殊情况:new_code不在字典中
string = oldString + oldString.charAt(0);
} else {
string = dictionary.get(newCode);
}
output.append(string);
// 将old_string + string[0]加入字典
if (dictSize < MAX_DICT_SIZE) {
dictionary.put(dictSize++, oldString + string.charAt(0));
}
oldString = string;
}
return output.toString();
}
/*
*
* 主函数
*/
public static void main(String[] args) {
String input = "TOBEORNOTTOBEORTOBEORNOT";
System.out.println("=== LZW压缩算法 ===");
System.out.println("原始文本: " + input);
List<Integer> compressed = compress(input);
System.out.println("压缩后编码: " + compressed);
String decompressed = decompress(compressed);
System.out.println("解压后文本: " + decompressed);
System.out.println("验证: " + input.equals(decompressed));
}
}