Tải bản đầy đủ (.doc) (47 trang)

Một số phương pháp nén cơ bản

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (241.32 KB, 47 trang )

Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản
mục lục

Mục lục
Lời nói đầu
Chơng I. Mã hoá theo mã loạt dài
I. Nguyên lý
II. Thuật toán nén
III. Thuật toán giải nén
Chơng II. Mã hoá theo mã Huffman
I. Nguyên lý
II. Thuật toán sinh mã
A. Quá trình thu gọn
B. Quá trình triển khai
III. Thuật toán nén
IV. Thuật toán giải nén
Chơng III. Mã hoá theo mã LZW
I. Nguyên lý mã hoá LZW
II. Thuật toán nén LZW
III. Thuật toán giải nén LZW
IV. Đánh giá thuật toán
Chơng IV. Đánh giá và kết quả thực nghiệm
I. Đánh giá các phơng pháp mã hoá trên phơng diện lý thuyết
II. Kết quả thực nghiệm và đánh giá
Kết luận
Phụ lục: Mã nguồn của các phơng pháp mã hoá
I. Phơng pháp mã hoá theo mã loạt dài
II. Phơng pháp mã hoã theo mã Huffman
1. Chơng trình nén


2. Chơng trình giải nén
III. Phơng pháp mã hoá theo mã LZW
Tài liệu tham khảo

Hồ Thị Ngọc Lan 39 A CNTT

Trang
1
2
3
3
3
5
7
7
8
8
10
14
15
17
17
17
22
26
29
29
30
32
33

33
35
35
41
43
49

1


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản
Lời nói đầu

Nh chúng ta biết, hầu hết các tệp dữ liệu thờng đợc lu trữ sao cho chúng
dễ dàng chạy đợc trên máy tính hay chính xác hơn là dễ dàng lu chúng trên
đĩa hoặc nạp vào bộ nhớ. Tuy nhiên, cách lu trữ này thờng làm cho tệp có
dung lợng lớn vì vậy khi muốn chuyển tải tệp giữa các máy tính với nhau
hoặc download từ trên mạng xuống là khá tốn kém và mất thời gian. Để khắc
phục vấn đề này ngời ta đã đa ra một số phơng pháp chuyển đổi dữ liệu từ
dạng "dễ sử dụng" sang dạng "tối u" gọi là nén. Thật vậy, giả sử ta muốn
download từ mạng Internet xuống máy tính cá nhân một bức ảnh có dung lợng
khoảng 600 Kbytes thì thời gian cần để download là khoảng 142 giây, tuy
nhiên nếu nh ảnh đó đợc nén thì dung lợng có thể chỉ còn khoảng 300 Kbytes
và thời gian cần thiết để download có thể chỉ là 71 giây.
Song song với quá trình nén là quá trình giải nén. Nếu nh nén là chuyển
dữ liệu về dạng "tối u" thì giải nén chính là quá trình khôi phục dữ liệu về
dạng gốc. Dựa vào kỹ thuật nén ngời ta chia thành hai kiểu nén đó là Lossless
và Lossy. Trong đó, Lossless là kiểu nén mà dữ liệu khi đợc khôi phục lại

giống hệt dữ liệu gốc, nó bao gồm các phơng pháp nh: Run - Length,
Huffman, Delta, LZW Còn Lossy là kiểu nén mà dữ liệu khi đ ợc khôi phục
lại chỉ cho kết quả tơng đơng, nó bao gồm các phơng pháp nh: CS&Q, JPEG,
MPEGBản chất của kiểu nén Lossless là chuyển các byte lặp hoặc chuỗi
các byte thành các từ mã vì vậy ngời ta còn gọi nén là mã hóa. Trong luận văn
này tôi chỉ xin trình bày một số phơng pháp mã hóa đơn giản trong kiểu nén
Lossless đó là :
1 Mã hóa theo mã loạt dài (Run - Length)
2 Mã hóa theo mã Huffman
3 Mã hóa theo mã LZW
Mục tiêu của luận văn chủ yếu tìm hiểu các phơng pháp mã hóa theo
kiểu Lossless, từ đó dựa trên một số mã nguồn đã có, sửa đổi nhằm hiểu sâu
hơn về giải thuật. Luận văn này đợc hoàn thành dới sự hớng dẫn và giúp đỡ
tận tình của thầy giáo Lê Văn Bằng. Dù đã cố gắng song chắc chắn không
tránh khỏi những thiếu sót, tôi mong đợc sự đóng góp ý kiến của các thầy cô
cùng các bạn.
Xin chân thành cảm ơn
Sinh viên: Hồ Thị Ngọc Lan

Hồ Thị Ngọc Lan 39 A CNTT

2


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

Chơng I. Mã hóa theo mã loạt dài.


I. Nguyên lý:
Trong các file dữ liệu thờng xuất hiện dãy các ký tự liên tiếp giống nhau
chẳng hạn nh : Tệp văn bản dùng các khoảng trắng để tách đoạn, xen kẽ giữa
các bài hát là một dãy dài các số 0, hoặc một hình ảnh bầu trời lúc nửa đêm sẽ
chứa dãy dài các ký tự màu đen... Rõ ràng, các tệp dữ liệu trên đã xảy ra hiện
tợng lu trữ dãy các ký tự lặp dẫn đến dung lợng tệp lớn. Để khắc phục hiện tợng này ngời ta đã đa ra phơng pháp nén dữ liệu dựa vào sự xuất hiện lặp lại
liên tiếp ký tự nào đó gọi là phơng pháp mã hóa theo mã loạt dài.
Nguyên lý: Trong một tệp dữ liệu xuất hiện các đoạn có các byte liên
tiếp có nội dung giống nhau thì có thể đợc biểu diễn bởi hai giá trị trong file
nén đó là:
Giá trị thứ nhất : Số lợng các byte trùng lặp
Giá trị thứ hai : Nội dung của các byte đó
Tuy nhiên, khi lu giá trị thứ nhất và giá trị thứ hai dới dạng các byte
chúng ta không phân biệt đợc đâu là giá trị thứ nhất và đâu là giá trị thứ hai.
Vì vậy, giá trị thứ nhất đợc lu dới dạng byte trong đó 3 bit cao nhất bằng 1 và
5 bit còn lại lu số lợng các byte trùng lặp (Số lần lặp không quá 31). Trong trờng hợp có byte chỉ xuất hiện một lần sẽ xảy ra hai trờng hợp :
Nếu giá trị của byte nhỏ hơn 224 thì để nguyên tức là lu dới dạng 1
byte
Ngợc lại, byte đợc lu bởi hai giá trị trong file nén :
+ Giá trị thứ nhất : Có dạng 11100000
+ Giá trị thứ hai : Nội dung của byte đó

Ví dụ :
Dòng dữ liệu gốc :

AAAA
3A b

CC
1C


2d

Dựa vào nguyên lý trên ta có thuật toán nén nh sau :

II. Thuật toán nén :
Bớc 1 : Lấy byte đầu tiên trong tệp dữ liệu
Bớc 2 : Lấy các byte tiếp theo. Kiểm tra xem các byte này có cùng giá
trị với byte trớc đó không ?
+ Nếu có thì đếm số lần lặp - giả sử là k (k <= 31). Khi đó, k byte trên
đợc mã hóa bởi cặp (byte_1, byte_2) trong đó, byte_1 có 3 bit cao nhất bằng 1

Hồ Thị Ngọc Lan 39 A CNTT

3


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

và 5 bit thấp có giá trị là số lợng các byte lặp còn byte_2 có giá trị là nội dung
của byte lặp.
+ Nếu không lặp xảy ra hai trờng hợp :
1 Nếu giá trị của byte nhỏ hơn 224 thì để nguyên byte đó
1 Ngợc lại, byte đó đợc mã hóa bởi cặp (byte_1, byte_2) trong đó byte_1 có 3
bit cao nhất bằng 1 và 5 bit thấp bằng 0 còn byte_2 có giá trị là nội dung của
byte đó.
Bớc 3 : Thực hiện cho đến khi hết tệp.
Trong đó :

1 Biến p : Lu giá trị của byte đọc từ tệp
1 Biến k : Số lần lặp của ký tự
1 byte_1 : Lu giá trị 224 + k
1 byte_2 : Lu nội dung của byte đợc
đọc vào

p0 = byte đầu tiên

pi = byte tiếp theo

pi = pi-1 ?

Sai

Đúng

Sai

k=k+1
Đúng

pi -1<224

Xuất pi -1

Sai

Đúng

k0


Sai

byte_1 = 224 + k
byte_2 = pi -1

byte_1 = 224
byte_2 = pi -1

Hết tệp ?

Đúng

Kết thúc

Hình 1 : Lu đồ thuật toán nén

1: Lu đồ thuật toán nén.
Hồ Thị Ngọc Lan 39 AHình
CNTT

4


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

Sơ đồ minh hoạ sự lu trữ các byte và bit trong bộ nhớ của xâu ký tự
AAAAbCCddde nh sau :

11 1 0 0 0 1 1 0 1 0 0 0 0 0 1 0 1 1 0 0 0 1 0 1 1 1 0 0 0 0 1
byte 1 =224 + 3
byte 2 =65 = A
byte 3 = 98 = b
byte 4 = 224 + 1
01 0 0 0 0 1 1 1 1 1 0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 1
byte 5 =67 = C
byte 6 =224 + 2
byte 7 = 100 = d byte 8 = 101 =e
Kết quả trong file nén xâu trên đợc mã hóa thành 8 byte có giá trị nh sau :
227, 65, 98, 225, 67, 226, 100, 101
Để khôi phục lại dữ liệu ban đầu cần phải giải nén. Sau đây là thuật toán mô tả
quá trình giải nén :

III. Thuật toán giải nén :
- Đọc 1 byte từ file nén .
- Kiểm tra xem byte đó có 3 bit cao nhất bằng 1 hay không ?
+ Nếu có thì kiểm tra xem 5 bit còn lại có giá trị bằng bao nhiêu - giả
sử bằng k. Khi đó, đọc byte tiếp theo và lu giá trị của byte đó ( k+1 ) lần trong
tệp kết quả.
+ Ngợc lại, nếu byte này có 3 bit cao nhất khác 1 thì lu giá trị của byte
đó vào tệp kết quả.
- Thực hiện cho đến khi hết tệp.
Thuật toán trên đợc mô tả dới dạng lu đồ khối ở hình 2 :

Hồ Thị Ngọc Lan 39 A CNTT

5



Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản
Bắt đầu

p = byte

Sai

p>=224

Đúng
Xuất p ra tệp

k = p - 224

p = byte tiếp theo

Xuất p ra tệp kết quả
(k +1) lần

Sai

Hết tệp ?

Đúng

Kết thúc

Hình 2 : Lu đồ thuật toán

giải nén

Trong đó :
Biến p : Lu giá trị của byte đợc đọc từ tệp vào.
Biến k : Số lần lặp của ký tự

áp dụng thuật toán giải nén cho ví dụ trên ta thu đợc dữ liệu trong tệp kết quả
là : AAAAbCCddde

Hồ Thị Ngọc Lan 39 A CNTT

6


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

Chơng II. mã hóa theo mã Huffman.

I. Nguyên lý.
Nếu nh mã hóa theo mã loạt dài dựa vào sự lặp lại liên tiếp của ký tự thì
mã hóa theo mã Huffman đợc xây dựng dựa trên sự phân bố ký tự. Trong một
tệp dữ liệu có một số ký tự thờng xuất hiện nhiều hơn các ký tự khác hay nói
cách khác, tần số xuất hiện nhiều hơn. Dựa vào đặc điểm đó Huffman đã đa ra
giải thuật gọi là mã Huffman. T tởng giải thuật là: thay thế những ký tự xuất
hiện nhiều hơn bằng các từ mã ngắn hơn và ngợc lại, thay thế các ký tự xuất
hiện ít hơn bằng các từ mã dài hơn. Vì vậy, để có thể mã hóa dữ liệu bằng phơng pháp Huffman có hiệu quả thì trớc hết chúng ta phải biết trớc tần số xuất
hiện của các ký tự.
Bộ từ mã đợc xây dựng theo mã Huffman bao gồm các từ mã thoả mãn

hai điều kiện ràng buộc sau :
Không có hai từ mã trùng nhau nghĩa là không có 2 byte dữ liệu khác
nhau nào đợc mã hóa bởi 1 từ mã
Không có từ mã nào là phần đầu của một từ mã khác có độ dài lớn hơn.
Chẳng hạn, nếu nh trong bộ từ mã đã có từ mã là 11101 thì sẽ không tồn tại
các từ mã nh : 1,11,111,1110. Nếu nh có các từ mã này trong bộ từ mã thì giải
mã sẽ cho kết quả không chính xác.
Nh vậy, công đoạn quan trọng nhất trong quá trình mã hóa đó là tìm các
từ mã. Mặt khác, từ mã lại đợc biểu diễn dới dạng nhị phân bao gồm các số 0
và 1 vì vậy ta có thể dùng cây nhị phân để tạo các từ mã trong đó nhánh có nút
con trái đợc đánh dấu là 1 và nhánh có nút con phải đợc đánh dấu là 0. Cụ thể
ta có thuật toán tạo cây nhị phân nh sau:
Bớc 1: Liệt kê tần số xuất hiện của các ký tự và tạo tập các nút lá là các
giá trị tần số xuất hiện.
Bớc 2: Tìm hai phần tử có số tần số nhỏ nhất từ tập nút để tạo thành nút
mới có giá trị bằng tổng 2 tần số đó gọi là nút cha .
Bớc 3: Tạo nút cha có giá trị là giá trị tần số mới và đánh dấu vào nhánh
con trái là 1 và nhánh con phải là 0.
Bớc 4: Cập nhật tập nút bằng cách thay thế 2 nút có tần số xuất hiện
thấp nhất bởi nút mới. Nếu tập nút chỉ bao gồm 1 nút thì thoát, ngợc lại thì
quay lại Bớc 2.
Sau khi đã xây dựng đợc cây nhị phân ta sẽ thu đợc từ mã của một kí tự
nào đó bằng cách xác định đờng đi từ gốc đến lá của kí tự đó.

Hồ Thị Ngọc Lan 39 A CNTT

7


Luận văn tốt nghiệp


Một số phơng pháp nén cơ bản

Từ những phân tích ở trên ta có thuật toán mã hóa theo mã Huffman
bao gồm 3 bớc chính sau:
Bớc 1: Tạo bảng xác suất theo thứ tự giảm dần từ dòng dữ liệu vào.
Bớc 2: Tạo cây nhị phân để tìm từ mã.
Bớc 3: Lần lợt đọc từng byte dữ liệu vào và thay thế các byte đó bởi các
từ mã ở dòng dữ liệu ra .
Song song với mã hóa là quá trình giải mã, tuy nhiên đối với phơng
pháp mã hóa theo mã Huffman thì để giải mã đợc chúng ta cần lu lại các từ
mã, vì các từ mã đợc lu lại dới dạng nhị phân nên một từ mã cần đợc lu bởi 2
giá trị : giá trị thứ 1 sẽ lu giá trị của từ mã còn giá trị thứ 2 sẽ lu số lợng các
bit nhị phân, chẳng hạn (4,3) tơng ứng với mã 100.
Theo thuật toán mã hóa thì bớc tạo cây nhị phân là phức tạp nhất vì thế
Huffman đã đa ra một phơng pháp để sinh mã cho các kí tự mà không cần
dùng cây nhị phân. Sau đây là thuật toán sinh mã theo Huffman:
II. Thuật toán sinh mã:
Thuật toán sinh mã đợc tiến hành trong 2 quá trình đó là: quá trình thu
gọn và quá trình triển khai. Để giải quyết quá trình sinh mã ta giả định rằng
tập các tần số xuất hiện của N kí tự đã đợc sắp xếp theo thứ tự giảm dần :
P(0)>=P(1)>=P(2)>=>=P(N-1)
Kí hiệu L(i) (i=0,N-1) là mảng chứa độ dài các từ mã, khi đó L(i) phải có thứ
tự tăng dần:
L(0)<=L(1)<=<=L(N-1)
A. Quá trình thu gọn:
Thuật toán quá trình thu gọn đợc mô tả nh sau:
1. Đặt M=N và giả sử V là mảng có kích thớc N-2 phần tử. Với mỗi i
từ 0 đến N-3 thì thực hiện các bớc sau:
{

2. Cộng P(M) vào P(M-1) và gán P(M-1) bởi tổng đó
3. Xác định vị trí j trong M-1 vị trí đầu tiên trong mảng P mà tại đó
P(M-1)=P(j)
4. Đặt temp=P(M-1)
5. Dịch chuyển tất cả các giá trị trong mảng P từ vị trí j đến vị trí M-2
xuống dới một vị trí
6. Thay thế P(j) bởi temp nghĩa là gán P(j)=temp
7. Lu vị trí đó vào mảng V nh sau:

Hồ Thị Ngọc Lan 39 A CNTT

8


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

V(N-2-i)=j
8. Giảm M đi 1
}
Ví dụ: Giả sử tần số xuất hiện các kí tự là:
P=( 0.25, 0.25, 0.125, 0.125, 0.0625, 0.0625, 0.0625, 0.0625 ) tơng ứng
với xâu kí tự : gAbAgEcEdeEfAEAf. Khi đó, ta có N=8.
Minh hoạ quá trình thu gọn:
1. M=N=8
Với i=0:
2. P(M-1)=P(M)+P(M-1)=P(8)+P(7)=0.125
3. Xác định đợc vị trí thứ 5 là vị trí đầu tiên trong mảng P mà tại
đó

P(M-1)>P(5). Khi đó j =5.
4. temp=P(M-1)=0.125.
5. Chuyển P(6) thành P(7) và P(5) thành P(6)
6. P(j)=temp=0.125 nghĩa là p(5)=0.125
7. V{N-2-i}=j nghĩa là V{6}=5.
8. Gán M=M-1 nghĩa là lúc này M=7
Tiếp tục quá trình trên với các giá trị i còn lại. Lu ý, khi i=5 thì tổng 2 số
hạng cuối cùng bằng 0.5 và bằng P(1) nên nó đợc đặt vào sau P(1) nghĩa là nó
đợc đặt vào vị trí thứ 2 lúc đó V(1) = 2.
P
i=0
i=1
i=2
i=3
i=4
i=5
TT
1
0.25
0.25
0.25
0.25
0.25
0.5
0.5
2
0.25
0.25
0.25
0.25

0.25
0.25
0.5
3
0.125
0.125
0.125
0.25
0.25
0.25
4
0.125
0.125
0.125
0.125
0.25
5
0.0625
0.125
0.125
0.125
6
0.0625
0.0625
0.125
7
0.0625
0.0625
8
0.0625

V[6] = 5

Lúc đó ta có :

V[5] = 6

V[4] = 3

V[3] = 4

V[2] = 1

V[1]=2

2
143
6
5

Hồ Thị Ngọc Lan 39 A CNTT

9


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

V=


Hình 3: Sơ đồ minh hoạ quá trình thu gọn.
Từ sơ đồ minh họa trên chúng ta có thể hình dung sơ đồ giống nh cây nhị
phân sau:
1

0.5

0.5

0.25

0.25

0.125

0.25

0.25

0.125

0.125

0.625

0.625

0.125

0.625


0.625

B. Quá trình triển khai.
Đây là giai đoạn tạo mã Huffman. ở giai đoạn này sử dụng mảng V đã
đợc tính ở quá trình thu gọn và khởi tạo thêm một mảng H để chứa độ lớn của
từ mã.
Quá trình triển khai đợc mô tả nh sau :
H(1)
1. Khởi tạo mảng H nh sau :
010
H(2)
0
H(3)
.
H=
=
H(4)
.
H(5)
0
.
.
H(N)
ở đây, chỉ có H(2)=1 còn các thành phần khác của mảng H là bằng 0. Vectơ
V=(V[1], V[2], V[3], V[N-2]) đã đợc tính trong quá trình thu gọn.

Hồ Thị Ngọc Lan 39 A CNTT

10



Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

2. Đặt M=2 và i=1
3. Lu giá trị tại vị trí V[i] trong mảng H vào một biến tạm thời có nghĩa
là temp=H(V[1]).
4. Dịch chuyển tất cả các thành phần sau H(V[i]) lên một vị trí. Sau đó,
chèn 0 vào vị trí sau cùng của mảng H.
5. Gán H(M)=temp
6. Dịch trái H(M) 1 bit
7. Gán H(M+1)=H(M)+1
8. Tăng M và i lên 1 đơn vị
9. Nếu i <=(N-2) thì quay lại bớc 3
Ngợc lại thì kết thúc và mảng H là từ mã cần tìm .
Để hiểu rõ thuật toán triển khai trên chúng ta sẽ đi minh hoạ ví dụ trong quá
trình thu gọn :
010
1. - Mảng V= (2,1,4,3,6,5) 000
00
- Mảng H:
H=

2. Đặt M = 2 và i = 1
3. temp = H(V[i]) = H(V[1]) = H(2) = 1
4. Lúc này, mảng H = ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
5. Gán H(M) = H(2) = temp nghĩa là lúc này H(2) = 1
6. Dịch trái H(M) 1 bit nghĩa là H(M) = 10

7. H(M +1) = H(M) + 1 nghĩa là H(3) = 10 + 1 = 11
8. Tăng M và i lên 1
Lặp lại các bớc trên cho đến khi i > N 2 ta sẽ thu đợc bộ từ mã
Huffman.

Sau đây là sơ đồ minh hoạ quá trình triển khai:
N H
i=1
i=2
i=3
i=4

Hồ Thị Ngọc Lan 39 A CNTT

i=5

i=6
11


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

1 0
0
10
10
10
10

10
2 1
10
11
11
11
11
11
3
11
00
00
010
010
010
4
01
010
011
011
011
5
011
000
000 0010
6
001 0010 0011
7
0011 0000
8

0001
Nh vậy, sau khi áp dụng thuật toán sinh mã cho ví dụ trên chúng ta thu đợc
bảng mã Huffman nh sau :
Tần số

Ký tự
xuất hiện
Huffman
A
0.25
10
E
0.25
11
f
0.125
010
g
0.125
011
d
0.0625
0000
e
0.0625
0001
b
0.0625
0010
c

0.0625
0011
Bảng 1 : Bảng mã Huffman
Nhận xét :
Thuật toán sinh mã này đợc xây dựng bởi Huffman. Tuy nhiên, Lu và
Chen phát hiện ra rằng thuật toán trên cho kết quả không đúng trong một số
trờng hợp. Chẳng hạn, trong trờng hợp chúng ta có tập tần số xuất hiện các ký
tự nh sau :
0.5
0.1
0.1
P = 0.1
0.1
0.1
áp dụng thuật toán thu gọn ta thu đợc:
223
2
V=

Hồ Thị Ngọc Lan 39 A CNTT

12


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

Sau đó, áp dụng thuật toán triển khai thu đợc bộ từ mã nh sau :
0

101
1000
H= 1001
110
111
rõ ràng, bộ từ mã trên không thoả mãn điều kiện độ dài từ mã tăng dần do mã
Huffman quy định, tuy nhiên nó vẫn cho kết quả đúng khi tiến hành giải mã. Lu
và Chen đã hoàn thiện thuật toán này bằng cách thay đổi điều kiện P(M-1) > P(j )
bởi điều kiện P(M-1) >= P(j ). Khi đó, kết quả thu đợc nh sau :

V=

122
2

Bộ từ mã :

H=

1
001
010
011
0000
0001

III. Thuật toán nén:
Giả sử ta đã thu đợc bộ mã Huffman sau khi sử dụng thuật toán sinh
mã. Lúc này, thuật toán nén đợc mô tả nh sau :
Lần lợt đọc từng ký tự từ dòng dữ liệu vào file gốc

Xác định từ mã cho từng ký tự (Dựa vào bộ mã Huffman)
Nhóm các bit của các từ mã thành các nhóm 8 bit ( 1 byte ) và lu
vào file kết quả. ( tệp tin mã hóa)
Thực hiện cho đến khi hết tệp

Ví dụ : Sử dụng bộ mã Huffman sau :
Ký tự
A
E
f
g

Hồ Thị Ngọc Lan 39 A CNTT


Huffman
10
11
010
011
13


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản
d
e
b
c


0000
0001
0010
0011

Quá trình mã hóa xâu ký tự gAbAgEcEdeEfAEAf đợc minh hoạ nh sau :
Xâu ký tự :
g

A
10

b
A
0010 10

011

g

E
11

c
0011

E
11


d
0000

e
0001

E
11

f
010

A
10

E
A
11 10

011

01110001

01001111

f

010

00111100


00000111

01010111

0010

Ví1dụ: Minh hoạ
thu đợc
quá 5trình nén
:
byte
bytequá
2 trình giải nén
bytetập
3 tin mã byte
4 trongbyte
byte6

Đọctoán giải nén:
IV. Thuật
từng
Thuật
toán
bit

bao

Từ các


gồm

Ký tự t-

bớc sau:ơng ứng

Tệp kết quả

1 Lần lợt đọc từng bit trong tập tin mã
0
0 Không có
Xác
từ mã có
dựa vào bộ mã Huffman
1 định ký tự tơng ứng
01 vớiKhông
1 ký tự tơng ứng đó011
g
Lu
vào tệp kếtg quả
1
1 Không có
g
Thực
hiện
cho
đến
khi
hết
tệp

tin

0
10
A
gA
0
0 Không có
gA
0
00 Không có
gA
1
001 Không có
gA
0
0010
b
gAb
1
1 Không có
gAb
0
10
A
gAbA
0
0 Không có
gAbA
1

01 Không có
gAbA
1
011
g
gAbAg
1
1 Không có
gAbAg
1
11
E
gAbAgE
0
0 Không có
gAbAgE
0
00 Không có
gAbAgE
1
001 Không có
gAbAgE
1
0011
c
gAbAgEc
1
1 Không có
gAbAgEc
1

11
E
gAbAgEcE
0
0 Không có
gAbAgEcE
0
00 Không có
gAbAgEcE

Hồ Thị Ngọc Lan 39 A CNTT

14


Luận văn tốt nghiệp
0
0
0
0
0
1
1
1
0
1
0
1
0
1

1
1
0
0
1
0

Một số phơng pháp nén cơ bản
000
0000
0
00
000
0001
1
11
0
01
010
1
10
1
11
1
10
0
01
010

Không có

d
Không có
Không có
Không có
e
Không có
E
Không có
Không có
f
Không có
A
Không có
E
Không có
A
Không có
Không có
f

gAbAgEcE
gAbAgEcEd
gAbAgEcEd
gAbAgEcEd
gAbAgEcEd
gAbAgEcEde
gAbAgEcEde
gAbAgEcEdeE
gAbAgEcEdeE
gAbAgEcEdeE

gAbAgEcEdeEf
gAbAgEcEdeEf
gAbAgEcEdeEfA
gAbAgEcEdeEfA
gAbAgEcEdeEfAE
gAbAgEcEdeEfAE
gAbAgEcEdeEfAEA
gAbAgEcEdeEfAEA
gAbAgEcEdeEfAEA
gAbAgEcEdeEfAEAf

Bảng 2. Minh hoạ quá trình giải nén.

Hồ Thị Ngọc Lan 39 A CNTT

15


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

Chơng III. Mã hóa theo mã LZW
LZW là tên viết tắt của ba nhà khoa học xây dựng nên thuật toán mã
hóa LZW đó là : A. Lempel, J. Ziv và Terry A .Welch.

I. Nguyên lý mã hóa LZW.
Nh chúng ta biết, trong các tệp dữ liệu thờng xuất hiện một số chuỗi
liên tiếp các ký tự sẽ tái xuất hiện với tần số tơng đối cao. Dựa trên vấn đề
này, A.Lempel và J.Ziv đã xây dựng nên thuật toán Lempel Ziv, sau đó Terry

A.Welch đã hoàn thiện thuật toán này. T tởng của thuật toán là: thay thế các
chuỗi ký tự bởi các mã số đơn lẻ.
Mã số đầu ra của thuật toán có độ dài có thể là tuỳ ý, tuy nhiên ở đây
ngời ta thờng dùng 12 bit để lu mã. Khi dùng 12 bit chúng ta sẽ có một bảng
chuỗi bao gồm 4096 chuỗi . Với những mã từ 0 đến 255 trong bảng mã thờng
đợc ngầm định cho những byte đơn chuẩn từ file gốc chẳng hạn ký tự A
có mã số là 65. Còn các mã từ 256 đến 4096 đ ợc gán cho các chuỗi ký
tự mới đợc thêm vào bảng mã trong quá trình thực hiện thuật toán, chẳng
hạn với mã 293 có thể đợc gán cho chuỗi ký tự ainl.
Khi quá trình nén thực hiện, thuật toán sẽ nhận ký tự hoặc chuỗi ký tự từ
file gốc và xử lý. Kết quả là mã số tơng ứng với ký tự hoặc chuỗi ký tự sẽ đợc đa
ra tệp kết quả (file nén) dới dạng 12 bit. Ngợc lại, trong quá trình giải nén, với mỗi
mã 12 bit sẽ đợc dịch thông qua bảng mã và trả lại kết quả là những byte đơn hoặc
là chuỗi các byte ở tệp kết quả (file đợc giải nén).
Có một điểm cần lu ý trong thuật toán mã hóa theo mã LZW đó là : Chuỗi
ký tự từ file gốc sẽ không đợc bổ sung vào bảng chuỗi nếu nh chuỗi đó đã xuất hiện
trong bảng chuỗi, hay nói khác đi mã của nó đã có mặt trong file nén.

II. Thuật toán nén LZW.
Bảng chuỗi ban đầu là bảng mã ASCII chuẩn bao gồm 256 xâu ký tự
với mỗi xâu là một ký tự đơn lẻ. Trong quá trình thuật toán nén thực hiện, các
xâu mới sẽ đợc bổ sung vào bảng chuỗi nhng bắt đầu từ xâu thứ 256 tơng ứng
với mã số 256. Vì vậy, thuật toán nén đợc mô tả nh sau:
Bớc 1 : Lấy byte đầu tiên và lu vào biến STRING
Bớc 2 : Lấy byte kế tiếp và lu vào biến CHAR
Bớc 3 : Kiểm tra xem xâu STRING + CHAR đã có trong bảng chuỗi
hay cha ?
+ Nếu có thì tạo chuỗi mới : STRING = STRING + CHAR

Hồ Thị Ngọc Lan 39 A CNTT


16


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

+ Ngợc lại, nếu cha có thì thực hiện các công việc sau :
Đa ra mã của xâu STRING
Thêm chuỗi STRING + CHAR vào bảng chuỗi
Gán STRING = CHAR
Bớc 4 : Thực hiện cho đến khi hết tệp và sang bớc 5. Nếu cha hết tệp thì
quay lại bớc 2.
Bớc 5 : Đa ra mã của xâu STRING.
Thuật toán này dùng hai biến là: biến STRING và biến CHAR. Biến
STRING dùng để lu trữ một xâu có độ dài thay đổi đó là một hoặc nhiều ký tự
với mỗi ký tự là một byte đơn. Còn biến CHAR dùng để lu trữ một ký tự đơn
lẻ với byte đơn có giá trị từ 0 đến 255.
Thuật toán này có thể đợc mô tả dới dạng lu đồ khối ở hình 3 :

Hồ Thị Ngọc Lan 39 A CNTT

17


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản


Lấy byte đầu tiên và lu
vào biến STRING

Lấy byte kế tiếp và lu
vào biến CHAR

Xâu
STRING +CHAR

Sai

đã có trong bảng


Đa ra mã của xâu
STRING

Đúng

Gán: STRING=
STRING + CHAR

Bổ sung: STRING +
CHAR vào bảng chuỗi

Gán :
STRING = CHAR

Sai


Hết tệp ?
Đúng
Đa ra mã của xâu
STRING

Kết thúc

Hình 3 : Lu đồ thuật toán nén

Hồ Thị Ngọc Lan 39 A CNTT

18


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

Bảng 3. Minh hoạ các bớc chi tiết trong thuật toán với dữ liệu là xâu văn bản
bằng tiếng Anh bao gồm 46 ký tự :
the / rain / in / spain / falls / mainly / on / the / plane /
STRING + CHAR
TT

String

CHAR

có trong bảng


Xuất mã

chuỗi hay cha ?

1
2
3
4
5
6
7
8
9

t
h
e
/
r
a
i
n
/

h
e
/
r
a
i

n
/
i

cha
cha
cha
cha
cha
cha
cha
cha
cha

10

i

n

có(262)

11
12
13
14

in
/
s

p

/
s
p
a

cha
cha
cha
cha

15

a

i

có(261)

16

ai

n

cha

17


n

/

có(263)

18
19
20
21
22
23
24
25

n/
f
a
l
l
s
/
m

f
a
l
l
s
/

m
a

cha
cha
cha
cha
cha
cha
cha
cha

26

a

i

có(261)

27

ai

n

có(269)

28
29

30
31

ain
l
y
/

l
y
/
o

cha
cha
cha
cha

t
h
e
/
r
a
i
n
/

262
/

s
p

261

263
f
a
l
l
s
/
m

269
l
y
/

Hồ Thị Ngọc Lan 39 A CNTT

Bổ sung chuỗi vào
bảng

Hành động

256 = th
257 = he
258 = e/
259 = /r

260 = ra
261 = ai
262 = in
263 = n/
264 = /i

Bổ sung chuỗi vào bảng
nt
nt
nt
nt
nt
nt
nt
nt
in đợc tìm thấy với mã là
262
265 = in/
Bổ sung chuỗi vào bảng
266 = /s
nt
267 = sp
nt
268 = pa
nt
ai đợc tìm thấy trong bảng
với mã là 261
269 = ain
Bổ sung chuỗi vào bảng
n/ có trong bảng với mã là

263
270 = n/f
Bổ sung chuỗi vào bảng
271 = fa
nt
272 = al
nt
273 = ll
nt
274 = ls
nt
275 = s/
nt
276 = /m
nt
277 = ma
nt
ai có trong bảng với mã là
261
ain có trong bảng với mã
là 269
278 = ainl
Bổ sung chuỗi vào bảng
279 = ly
nt
280 = y/
nt
281 = /o
nt


19


Luận văn tốt nghiệp
32

o

n

33

n

/

34

n/

t

35

t

h

36
37

38
39
40
41
42
43
44

th
e
e/
p
l
a
n
e
e/

e
/
p
l
a
n
e
/
EOF

Một số phơng pháp nén cơ bản
cha


o

282 = on

nt
n/ có trong bảng với mã là
có(263)
263
cha
263 283 = n/t
Bổ sung chuỗi vào bảng
th có trong bảng với mã là
có(256)
256
cha
256 284 = the
Bổ sung chuỗi vào bảng
có(258)
e/ có trong bảng chuỗi
cha
258 285 = e/p
Bổ sung chuỗi vào bảng
cha
p
286 = pl
nt
cha
l
287 = la

nt
cha
a
288 = an
nt
cha
n
289 = ne
nt
có(258)
e/ có trong bảng chuỗi
258
Hết tệp. Cho ra mã của e/
Bảng 3. Quá trình nén LZW

Đầu tiên, chuỗi đầu vào là ký tự ' t ' và đợc gán cho biến STRING .
Tiếp tục lấy ký tự tiếp theo và gán cho biến CHAR lúc này, CHAR =' h '. Sau
đó, kiểm tra xem xâu STRING + CHAR đã có trong bảng cha ? Rõ ràng ta
thấy xâu th cha xuất hiện trong bảng vì vậy xâu th sẽ đợc bổ sung vào
bảng chuỗi có mã tơng ứng là 256.
Làm tơng tự với các byte từ dòng 2 đến dòng 9 trong bảng 3 ta sẽ có các
chuỗi mới trong bảng chuỗi. ở dòng thứ 10, xâu STRING + CHAR = in là
xâu đã xuất hiện trong bảng chuỗi với mã là 262 nên xâu in sẽ đợc gán cho
biến STRING nghĩa là STRING = in. ở dòng 11, xâu STRING + CHAR =
in/ cha có trong bảng vì thế xâu in/ với mã tơng ứng là 265 sẽ đợc bổ sung
vào bảng. Cứ tiếp tục thực hiện cho đến khi hết tệp và lúc này các mã trở
thành đầu ra.
Kết quả ở file nén có nội dung nh sau :
the / rain / 262 / sp261263falls / m269ly / o263256258plan258


II.Thuật toán giải nén LZW.
Khi tiến hành giải nén, cần phải lấy đợc dòng mã đầu ra từ thuật giải nén
và sử dụng nó để tạo lại dòng dữ liệu vào một cách chính xác. Tuy nhiên, trong
quá trình giải nén không cần phải duyệt lại bảng chuỗi đã đợc xây dựng từ thuật
giải nén, mà bảng này sẽ đợc thiết lập lại giống hệt bảng chuỗi khi thực hiện nén
LZW và sử dụng nó để giải nén dòng dữ liệu vào. Điều này là có thể thực hiện
đợc vì thuật toán nén luôn luôn xuất ra các thành phần STRING và CHAR của

Hồ Thị Ngọc Lan 39 A CNTT

20


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

một mã trớc khi nó sử dụng trong luồng ra, nghĩa là dữ liệu đợc nén không bị lớn
lên vì phải mang theo bảng dịch xâu dẫn đến dung lợng tệp nén sẽ giảm đi. Thuật
toán toán giải nén đợc mô tả nh sau :
Bớc 1 : Đọc mã đầu tiên và lu vào biến OCODE. Sau đó, xuất ra chuỗi
tơng ứng của OCODE.
Bớc 2 : Đọc mã kế tiếp và lu vào NCODE
Bớc 3 : Kiểm tra xem NCODE đã có trong bảng chuỗi hay cha ?
+ Nếu có thì gán STRING bằng chuỗi tơng ứng của NCODE
+ Ngợc lại, thực hiện công việc sau :
Gán STRING bằng chuỗi tơng ứng của OCODE
Gán STRING = STRING + CHAR
Bớc 4 : Xuất ra nội dung của STRING
Bớc 5 : Gán CHAR bằng ký tự đầu tiên của xâu STRING

Bớc 6 : Bổ sung OCODE + CHAR vào bảng chuỗi
Bớc 7 : Gán OCODE = NCODE
Bớc 8 : Kiểm tra xem đã hết tệp cha ?
Nếu hết tệp thì kết thúc.Ngợc lại, quay lại Bớc 2
Trong thuật toán này sử dụng 4 biến là OCODE, NCODE, STRING và CHAR
trong đó :
Biến OCODE : Dùng để lu trữ mã cũ
NCODE : Dùng để lu trữ mã mới
CHAR : Lu trữ byte đơn lẻ
STRING : Lu trữ chuỗi các byte

Tơng tự nh thuật toán nén, thuật toán giải nén cũng bổ sung xâu mới
vào bảng chuỗi mỗi lần đọc vào một mã mới. Kết quả bảng chuỗi này giống
hệt bảng chuỗi thu đợc khi thực hiện thuật toán nén và xâu xuất ra tệp kết quả
giống hệt xâu vào trong thuật toán nén. Lu ý là 256 mã đầu tiên của bảng
chuỗi đợc ngầm định để chuyển thành các byte đơn lẻ.
Thuật toán trên đợc mô tả dới dạng lu đồ khối ở hình 4:

Hồ Thị Ngọc Lan 39 A CNTT

21


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

Bắt đầu

Đọc mã đầu tiên và lu

vào biến OCODE
Xuất ra chuỗi tơng
ứng của OCODE
Đọc mã tiếp theo và lu
vào biến NCODE

NCODE có trong
bảng ?
Gán:
STRING = chuỗi tơng
ứng của OCODE

Gán:
STRING = chuỗi tơng ứng của
NCODE

Gán:
STRING= STRING + CHAR

Xuất ra nội dung của
STRING
CHAR= kí tự đầu tiên
của xâu STRING
Gán OCODE=NCODE
Bổ sung OCODE +CHAR
vào bảng chuỗi

Hình 4: Lu đồ thuật toán giải nén LZW
Hết
tệp ?


Kết thúc

Bảng 4. Minh hoạ quá trình giải nén tệp vào có nội dung nh sau:
the / rain / 262 / sp261 263 falls / m269 ly / o263 256 258 plan 258.
Hình
4: LuNgọc
đồ thuật
toán
Hồ Thị
Lan
39giải
ASainén.
CNTT
Sai
Gán: OCODE=NCODEĐúng
Đúng

22


Luận văn tốt nghiệp
NCODE
TT OCODE NCODE có trong
bảng ?
1
t
2
h


3
h
e

4
e
/

5
/
r

6
r
a

7
a
i

8
i
n

9
n
/

10
/

262

11
262
/

12
/
s

13
s
p

14
p
261

15
261
263

16
263
f

17
f
a


18
a
l

19
l
l

20
l
s

21
s
/

22
/
m

23
m
269

24
269
l

25
l

y

26
y
/

27
/
o

28
o
263

29
263
256

30
256
258

31
258
p

32
p
l


33
l
a

34
a
n

35
n
258

36
258
EOF

Một số phơng pháp nén cơ bản
Chuỗi
CHAR STRING
đầu ra
t
h
e
/
r
a
i
n
/
in

/
s
p
ai
n/
f
a
l
l
s
/
m
ain
l
y
/
o
n/
th
e/
p
l
a
n
e/

h
e
/
r

a
i
n
/
i
/
s
p
a
n
f
a
l
l
s
/
m
a
l
y
/
o
n
t
e
p
l
a
n
e


h
e
/
r
a
i
n
/
in
/
s
p
ai
n/
f
a
l
l
s
/
m
ain
l
y
/
o
n/
th
e/

p
l
a
n
e/

Chuỗi mới

256 = th
257 = he
258 = e/
259 = /r
260 = ra
261 = ai
262 = in
263 = n/
264 = /i
265 = in/
266 = /s
267 = sp
268 = pa
269 = ain
270 = n/f
271 = fa
272 = al
273 = ll
274 = ls
275 = s/
276 = /m
277 = ma

278 = ainl
279 = ly
280 = y/
281 = /o
282 = on
283 = n/t
284 = the
285 = e/p
286 = pl
287 = la
288 = an
259 = ne

Bảng 4. Quá trình giải nén LZW.
Đầu tiên, thuật toán giải nén sẽ đọc mã đầu tiên và lu vào biến OCODE
lúc này OCODE = t , khi đó chuỗi xuất ra là kí tự t . Tiếp theo, mã kế

Hồ Thị Ngọc Lan 39 A CNTT

23


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

tiếp đợc đọc và lu vào biến NCODE, lúc này NCODE = h. Đến đây, thuật toán
sẽ kiểm tra xem NCODE nghĩa là mã của kí tự h có trong bảng chuỗi hay
không ? Rõ ràng, mã của kí tự h bằng 104 có trong bảng chuỗi vì vậy biến
STRING sẽ đợc gán bằng chuỗi tơng ứng của NCODE nghĩa là lúc này STRING

= h . Kế đó, thuật toán xuất ra nội dung của STRING nghĩa là chuỗi xuất ra là
kí tự h . Biến CHAR đợc gán bằng kí tự đầu tiên trong STRING nghĩa là
CHAR sẽ bằng h. Tiếp theo, bổ sung OCODE + CHAR vào bảng chuỗi khi
đó trong bảng chuỗi sẽ xuất hiện thêm một chuỗi mới với mã là 256 ( 256 = th ).
Cuối cùng, gán OCODE = NCODE nghĩa là lúc này OCODE sẽ bằng h. Cứ tiếp
tục thực hiện cho đến khi hết tệp. Kết quả ở tệp mới có nội dung nh sau:
the / rain / in / spain / falls / mainly / on / the / plane/

IV. Đánh giá thuật toán:
Thuật toán này thực sự là đơn giản mà hiệu quả sử dụng lại rất cao. Tuy
nhiên, xét trên một khía cạnh nào đó thì thuật toán lại khá phức tạp. Thuật
toán phức tạp ở chổ quản lý bảng chuỗi. Khi nén dữ liệu ngời ta thờng dùng
12 bit để lu trữ mã khi đó có đến 4096 chuỗi trong một bảng. Mỗi lần một kí
tự đợc đọc vào thì việc tìm kiếm chuỗi tơng ứng lại diễn ra. Nếu nh không tìm
thấy thì chuỗi mới sẽ đợc bổ sung vào bảng chuỗi.
Điều này sẽ gây ra hai vấn đề : Đầu tiên, ta có thể nhận thấy rằng bảng chuỗi có thể
lớn rất nhanh, thêm vào đó thì tổng số chuỗi cần thiết cho một bảng là không biết trớc
đợc bởi vì số lợng chuỗi đợc hình thành phụ thuộc vào tổng chiều dài của tất cả các
xâu. Vấn đề này có thể đợc giải quyết bằng cách lu trữ các chuỗi dới dạng là sự
kết hợp giữa mã đã có và một kí tự mới nghĩa là mọi mã có thể đợc xây dựng
bởi mã trớc đó bằng cách bổ sung thêm một kí tự mới, nó có dạng nh sau : mã
đơn lẻ + ký tự mới. Chẳng hạn, trong ví dụ nén ở trên mã 278 đợc định nghĩa
cho chuỗi ainl. Tuy nhiên, mã 278 tơng ứng với chuỗi ''ainl'' có thể đợc lu trữ bởi
mã 269 + l vì mã 269 tơng ứng với chuỗi ''ain''. Tơng tự, mã 269 lại có thể đợc lu
trữ bởi mã 261 + n, mã 261 có thể đợc lu trữ nh là kí tự a + i.
Vấn đề thứ 2 là vấn đề liên quan đến việc tìm kiếm chuỗi để xác định
phần tử đợc biểu diễn tơng ứng. Mỗi lần một kí tự mới đợc đọc vào, quá trình
nén thực hiện việc tìm kiếm chuỗi mới do chuỗi cũ và kí tự mới hình thành
nên. Điều này, dẫn đến bảng chuỗi phải đợc sắp xếp theo một trình tự nào đó.
Việc tìm kiếm chuỗi trong bảng đã sắp xếp sẽ nhanh hơn rất nhiều tuy nhiên

việc tạo bảng chuỗi nh vậy rất mất thời gian. Sở dĩ nh vậy là vì khi lập bảng
chuỗi đợc sắp xếp theo một trình tự nào đó thì khi chuỗi mới đợc thêm vào, nó

Hồ Thị Ngọc Lan 39 A CNTT

24


Luận văn tốt nghiệp

Một số phơng pháp nén cơ bản

phải đợc chèn vào đúng vị trí của nó. Điều này thật sự là tốn công dẫn đến
''chi phí'' cho vấn đề này lớn.
Tìm kiếm chuỗi sẽ gặp khó khăn ở công đoạn so sánh chuỗi vì vậy khi áp
dụng thuật toán này chúng ta sẽ không ấn định 4096 chuỗi theo một thứ tự nào
đó mà sử dụng một phơng pháp lu trữ khác đó là phơng pháp lu trữ sử dụng
thuật toán Băm. Khi sử dụng phơng pháp này, thời gian so sánh chuỗi sẽ giảm
đi, tuy nhiên nó lại không cho chúng ta biết số lần so sánh cần thiết để tìm
kiếm chuỗi. Khi lu trữ chuỗi bằng thuật toán Băm thì mã 256 có thể không ở
vị trí 256 trong bảng mà đợc định vị trong một mảng dựa vào địa chỉ đợc tạo
thành bởi chính xâu đó. Khi muốn định vị cho chuỗi ta sẽ sử dụng bộ dò xâu
để tạo nên địa chỉ Băm. Nếu nh may mắn có thể tìm thấy chuỗi mục tiêu trong
một lần tìm kiếm. Nếu mã của chuỗi cho trớc không còn đợc biết bởi vị trí của
nó trong mảng thì cần lu mã của chuỗi đó cùng với dữ liệu của chuỗi bao gồm
giá trị mã [i], mã tiền tố [i] và kí tự bổ sung [i].
Khi muốn bổ sung một mã mới vào bảng chuỗi chúng ta sẽ sử dụng hàm
Băm theo quy tắc Tìm làm khớp để tạo nên địa chỉ, sau đó kiểm tra xem nếu
vị trí đó đã đợc dùng cho chuỗi khác thì nó sẽ tìm kiếm vị trí thứ 2. Quá trình cứ
tiếp tục cho đến khi một vị trí mở đợc tìm thấy.

Hàm Băm sử trong thuật toán này là một dạng hàm Băm kiểu XOR. Mã
tiền tố và kí tự bổ sung đợc kết hợp lại tạo thành một địa chỉ mảng. Nếu nội
dung của mã tiền tố và kí tự bổ sung khớp với một phần tử nào đó của mảng
thì nó sẽ cho ta một địa chỉ xác định. Nếu một phần tử trong mảng đang đợc
sử dụng thì phần tiền tố đợc dùng để tìm kiếm vị trí mới. Cứ tiếp tục cho
đến khi khe trống đợc tìm thấy hoặc một phần tử đợc tìm thấy. Ta nhận thấy
rằng lần tìm kiếm lần thứ 2 luôn xảy ra và kích thớc mảng phải là một số
nguyên tố. Sở dĩ nh vậy là vì số lần tìm kiếm có thể là một số nguyên bất kì từ
0 đến kích thớc của bảng. Nếu nh số lần tìm kiếm và kích thớc của bảng
không phải là số nguyên tố thì việc tìm kiếm khe trống có thể bị lỗi ngay cả
khi có nhiều khe trống đang rỗi. Trong khi ở quá trình nén chúng ta cần tìm
kiếm xâu trong bảng chuỗi thì ngợc lại trong quá trình giải nén chúng ta lại
tiến hành tìm từng mã riêng biệt. Điều này lu ý chúng ta có thể lu trữ các mã
tiền tố và các kí tự bổ sung trong bảng theo thứ tự mã xâu của chúng vì vậy
trong thuật toán giải nén ta không cần sử dụng hàm Băm.
Một nhợc điểm khác ở phơng pháp này là xuất hiện đụng độ khi đọc
vào một dòng dữ liệu không xác định hoặc khi gặp dấu hiệu kết thúc tệp. Để
giải quyết vấn đề này ta sẽ sử dụng biến MAX_VALUE làm dấu hiệu kết thúc

Hồ Thị Ngọc Lan 39 A CNTT

25


×