CFSDN nhấn mạnh vào giá trị tạo ra nguồn mở và chúng tôi cam kết xây dựng nền tảng chia sẻ tài nguyên để mọi nhân viên CNTT có thể tìm thấy thế giới tuyệt vời của bạn tại đây.
Bài viết trên blog CFSDN Giải thích nén và giải nén từ điển thuật toán Java Compression LZW này được tác giả sưu tầm và biên soạn. Nếu các bạn quan tâm tới bài viết này thì nhớ like nhé.
Quá trình nén:
Tôi đã viết một bài về nén Huffman trước đây. Sự khác biệt giữa nén từ điển lzw và nén Huffman là việc mã hóa không cần phải ghi vào tệp. Bảng mã hóa được tạo bằng cách đọc tệp. được kết hợp với các số tương ứng được lưu trữ trong bảng băm dưới dạng bảng mã cơ bản.

Hậu tố ở đây là hiện tại.
Nếu tiền tố + hậu tố tồn tại trong bảng mã thì tiền tố bằng tiền tố + hậu tố. Nếu chưa tồn tại thì ghi chuỗi biểu thị bằng tiền tố + hậu tố vào bảng mã hóa, đồng thời ghi tiền tố vào file nén. Điều quan trọng cần lưu ý ở đây là phạm vi số có thể được biểu thị bằng một byte là 0-255, vì vậy chúng tôi thay đổi mã hóa của một ký tự thành hai byte và ghi tám bit cao và tám bit thấp tương ứng, chẳng hạn như 256 That là 00000001 11111111 Phương thức dos.writechar(256) trong đối tượng dataoutputstream dos được sử dụng ở đây.
Phạm vi mà hai byte có thể biểu thị là 0-65535. Khi mã hóa của chúng tôi vượt quá phạm vi này, chúng tôi cần đặt lại bảng mã hóa và mã hóa lại.
quá trình giải nén.

cw đại diện cho ký tự đã đọc, pw là cw của dòng trước, cw bảng mã hóa lại tồn tại: p→pw, c→cw ký tự đầu tiên, đầu ra cw. cw không tồn tại trong bảng mã hóa, ký tự đầu tiên của p→pw, c→pw được xuất ra dưới dạng p+c.
Khi đọc 65535, chúng ta đặt lại bảng mã và mã hóa lại.
phần mã.
?
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
|
công cộng
lớp học
yasuo {
riêng tư
số nguyên
bianma =
256
;
riêng tư
tiền tố chuỗi =
""
;
riêng tư
hậu tố chuỗi =
""
;
riêng tư
chuỗi trung kiến =
""
;
hashmap hm =
mới
hashmap();
riêng tư
tĩnh
đường dẫn chuỗi =
"d:\\java\\Nén từ điển\\ziidianyasuo.txt"
;
riêng tư
tĩnh
chuỗi path2 =
"d:\\java\\Nén từ điển\\yasuo.txt"
;
riêng tư
tĩnh
chuỗi path3 =
"d:\\java\\Nén từ điển\\jieya.txt"
;
công cộng
tĩnh
vô hiệu
main(chuỗi[] args)
ném
ngoại lệ io {
/**
* Nén
*/
yasuo yasuo =
mới
yasuo();
yasuo.yasuo();
/**
* Giải nén
*/
jieya jie =
mới
jieya();
jie.jieya(path2,path3);
}
công cộng
vô hiệu
yasuo()
ném
ngoại lệ io {
luồng đầu vào là =
mới
fileinputstream(đường dẫn);
byte
[] bộ đệm =
mới
byte
[is.available()];
is.read(bộ đệm);
chuỗi str =
mới
chuỗi(bộ đệm);
is.close();
luồng đầu ra os =
mới
fileoutputstream(đường dẫn2);
luồng dữ liệu đầu ra dos =
mới
luồng dữ liệu đầu ra(os);
vì
(
số nguyên
tôi =
0
; tôi <
256
; tôi++) {
char
ch = (
char
) Tôi;
chuỗi st = ch +
""
;
hm.put(st, i);
}
vì
(
số nguyên
tôi =
0
; i < độ dài chuỗi(); i++) {
nếu như
(bianma==
65535
){
hệ thống.out.println(
"cài lại"
);
dos.writechar(
65535
);
hm. xóa();
vì
(
số nguyên
j =
0
; j <
256
; j++) {
char
ch = (
char
) j;
chuỗi st = ch +
""
;
hm. đặt(st, j);
}
tiền tố=
""
;
bianma=
0
;
}
char
ch = str.charat(i);
chuỗi s = ch +
""
;
hậu tố = s;
trung kiến = tiền tố + hậu tố;
nếu như
(hm.get(trung kiên) ==
vô giá trị
) {
hm.put(zhongjian, bianma);
dos.writechar(hm.get(tiền tố));
biama++;
tiền tố = hậu tố;
}
khác
{
tiền tố = trung giám;
}
nếu như
(i == chiều dài chuỗi() -
1
) {
dos.writechar(hm.get(tiền tố));
}
}
os. đóng();
}
}
|
?
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
|
công cộng
lớp học
jieya {
riêng tư
arraylist danh sách =
mới
arraylist();
riêng tư
số nguyên
đếm =
0
;
riêng tư
arraylist numlist =
mới
danh sách mảng<>();
hashmap hm =
mới
bản đồ băm <>();
hashmap hm1 =
mới
bản đồ băm <>();
riêng tư
chuỗi cw =
""
;
riêng tư
chuỗi pw =
""
;
riêng tư
chuỗi p =
""
;
riêng tư
chuỗi c =
""
;
riêng tư
số nguyên
bianma =
256
;
công cộng
vô hiệu
jieya(đường dẫn chuỗi, đường dẫn chuỗi1)
ném
ngoại lệ io {
luồng đầu vào là =
mới
fileinputstream(đường dẫn);
byte
[] bộ đệm =
mới
byte
[is.available()];
is.read(bộ đệm);
is.close();
chuỗi str =
mới
chuỗi(bộ đệm);
vì
(
số nguyên
tôi =
0
; i < chiều dài bộ đệm; i +=
2
) {
số nguyên
a = bộ đệm[i];
danh sách.thêm(a);
}
vì
(
số nguyên
tôi =
1
; i < chiều dài bộ đệm; i +=
2
) {
nếu như
(bộ đệm[i] == -
1
&& bộ đệm[i -
1
] == -
1
) {
numlist.add(
65535
);
}
khác
{
nếu như
(list.get(đếm) >
0
) {
nếu như
(bộ đệm[i] <
0
) {
số nguyên
a = bộ đệm[i] +
256
+
256
* list.get(đếm);
numlist.add(a);
}
khác
{
số nguyên
a = bộ đệm[i] +
256
* (list.get(đếm));
numlist.add(a);
}
}
khác
{
numlist.add((
số nguyên
) bộ đệm[i]);
}
đếm++;
}
}
/**
* Mã hóa 0-255 ký tự
*/
vì
(
số nguyên
tôi =
0
; tôi <
256
; tôi++) {
char
ch = (
char
) Tôi;
chuỗi st = ch +
""
;
hm.put(st, i);
hm1.put(i, st);
}
/**
* Bắt đầu mã hóa lại theo các thành phần trong hàng đợi danh sách số và xuất tệp
*/
luồng đầu ra os =
mới
fileoutputstream(đường dẫn1);
vì
(
số nguyên
tôi =
0
; i < kích thước danh sách số(); i++) {
số nguyên
n = numlist.get(i);
nếu như
(hm.chứagiátrị(n) ==
ĐÚNG VẬY
) {
cw = hm1.get(n);
nếu như
(pw !=
""
) {
os.write(cw.getbytes(
"gbk"
));
p = pw;
c = cw. charat(
0
) +
""
;
hm.put(p + c, bianma);
hm1.put(bianma, p + c);
biama++;
}
khác
{
os.write(cw.getbytes(
"gbk"
));
}
}
khác
{
p = pw;
c = pw. charat(
0
) +
""
;
hm.put(p + c, bianma);
hm1.put(bianma, p + c);
biama++;
os.write((p + c).getbytes(
"gbk"
));
cw = p + c;
}
pw = cw;
nếu như
(tôi ==
65535
) {
hệ thống.out.println(
"Đặt lại 2"
);
hm. xóa();
hm1. xóa();
vì
(
số nguyên
j =
0
; j <
256
; j++) {
char
ch = (
char
) j;
chuỗi st = ch +
""
;
hm. đặt(st, j);
hm1.put(j, st);
}
bianma =
0
;
tiền =
""
;
}
}
os. đóng();
}
}
|
Nhược điểm: Khi mã hóa vượt quá 65535 thì xử lý không tốt và không thể đặt lại bảng mã. Tệp được khôi phục bắt đầu bị cắt xén ở phần vượt quá 65535. Vẫn cần phải được cải thiện.
Tóm tắt.
Trên đây là toàn bộ nội dung bài viết mong rằng nội dung bài viết có giá trị tham khảo và học tập nhất định cho quá trình học tập, làm việc của mọi người. Nếu bạn muốn biết thêm về nó, vui lòng xem các liên kết liên quan bên dưới.
Liên kết gốc: https://blog.csdn.net/lzq1326253299/article/details/82750568.
Cuối cùng, bài viết giải thích về nén và giải nén từ điển thuật toán LZW của nén Java kết thúc ở đây. Nếu bạn muốn biết thêm về giải thích về nén và giải nén từ điển thuật toán LZW của nén Java, vui lòng tìm kiếm các bài viết CFSDN hoặc tiếp tục duyệt qua các bài liên quan. Bài viết, tôi hy vọng bạn sẽ ủng hộ blog của tôi trong tương lai! .
Tôi là một lập trình viên xuất sắc, rất giỏi!