Các thuật toán nén LZ

Một phần của tài liệu nén văn bản tiếng việt theo huffman (Trang 48)

5. Ý nghĩa khoa học của luận văn

2.4.4.Các thuật toán nén LZ

2.4.4.1. Thuật toán LZ77:

Quá trình nén

Gọi vị trí kí tự đang đọc là hiện tại.

Gọi khoảng văn bản bắt đầu từ vị trí của kí tự đang được đọc đến hết văn bản là tương lai.

Gọi khoảng văn bản từ bắt đầu văn bản đến ngay trước vị trí kí tự đang được đọc là quá khứ.

Chúng ta chỉ tìm trong một khoảng N kí tự của quá khứ mà gần hiện tại nhất và tìm trong khoảng F kí tự đầu tiên trong tương lai và gọi F kí tự này là buffer.

Nguyên tắc nén như sau:

Bước 1: F – 1 kí tự đầu tiên giữ nguyên.

Bước 2: Cho buffer gồm F kí tự trong tương lai dịch dần về quá khứ N lần. Mỗi lần đếm số kí tự trùng nhau liên tiếp kể từ đầu của buffer với quá khứ và ghi nhớ con số ấy tương ứng với các vị trí quá khứ mà buffer dịch đến. Tìm số lớn nhất trong tất cả các con số ấy.

Bước 3: Ghi ra mã gồm [i, j, w] trong đó i là khoảng cách từ vị trí hiện tại đến vị trí tương ứng với số lớn nhất vừa tìm được, j là số các kí tự trùng nhau hay chính là số lớn nhất vừa tìm được, w là kí tự ở vị trí thứ j + 1 trong buffer.

Bước 4: Lặp lại bước 2 cho đến khi hết văn bản.

Quá trình giải nén

Bước 1: Đọc F – 1 kí tự đầu tiên của bản mã ghi ra bản giải mã.

Bước 2: Đọc một bộ mã [i, j, w]. Lùi về đoạn văn bản đã giải mã i vị trí và copy j kí tự từ vị trí thứ i đó để ghi ra bản giải mã, sau đó ghi ra w .

Bước 3: Nếu còn bộ mã thì quay lại bước 2. Nếu không còn thì kết thúc.

Ví dụ

Quá trình nén như sau:

TT Quá khứ Vị trí hiện tại Buffer Ghi ra

1 bca

2 bca 4 bbcb [3,1,b]

3 bcabb 6 cbcc [4,1,b]

4 bcabbcb 8 ccba [2,1,c]

5 bcabbcbcc 10 baba [3,1,a]

6 bcabbcbccba 12 babc [2,2,b]

7 bcabbcbccbaba 15 c [5,1,””]

Bản mã là bca[3,1,b][4,1,b][2,1,c][3,1a][2,2,b][5,1,””]

Quá trình giải nén

TT Bộ mã đọc vào Ghi ra Bản giải mã

1 bca bca 2 [3,1,b] bb bcabb 3 [4,1,b] cb bcabbcb 4 [2,1,c] cc bcabbcbcc 5 [3,1,a] ba bcabbcbccba 6 [2,2,b] bab bcabbcbccbabab 7 [5,1,””] c bcabbcbccbababc

2.4.4.2. Thuật toán LZ78:

Đây là một trong các thuật toán từ điển động khá mạnh đ ược phát minh và sử dụng trong những năm 1978. Từ điển xây dựng trong mã hoá và giải mã đơn giản và hoàn toàn động, do đó không cần lưu từ điển cùng file nén. (adsbygoogle = window.adsbygoogle || []).push({});

Quá trình nén

Thuật toán nén.

Bước 1: Khởi tạo từ điển có một phần tử là xâu rỗng có chỉ số 0. Xâ u trung gian P rỗng.

Bước 2: Đọc kí tự tiếp theo trong văn bản vào C.

Bước 3: Tìm khúc (P + C) đã có trong từ điển chưa?  Nếu có thì P ← P + C và quay lại bước 2.  Nếu không thì:

i. Cập nhật P + C vào trong từ điển. ii. W ← chỉ số của P trong từ điển. iii. Ghi cặp (W, C) ra bản mã. iv. P ← rỗng.

Bước 4: Còn kí tự trong văn bản vào?  Nếu còn thì quay lại bước 2.

 Nếu không còn thì ghi ra cặp (W, C) với C là rỗng.

Hình 13. Sơ đồ nén LZ78

Bắt đầu

Khởi tạo từ điển. Xâu trung gian P rỗng

Đọc kí tự tiếp theo vào C

P + C đã có

trong từ điển? P ← P + C

W ← chỉ số của P trong từ điển

Ghi ra bản mã (W, C) Cập nhật P + C vào từ điển P ← rỗng Còn kí tự trong văn bản? C ← rỗng Kết thúc Ghi ra bản mã (W, C) Đúng Đúng Sai i Sai

Quá trình giải nén

Với mỗi cặp (W, C) ta ký hiệu .W nội dung của đoạn copy thứ W trong từ điển. Nếu W = 0 thì .W là rỗng.

Thuật toán giải nén.

Bước 1: Khởi tạo từ điển có một phần tử là xâu rỗng có chỉ số 0.

Bước 2: Đọc một cặp (W, C).

Bước 3: Ghi xâu (.W + C) ra bản giải mã. Cập nhật xâu này vào từ điển.

Bước 4: Còn kí tự trong bản mã không?

 Nếu còn thì đọc cặp (W, C) tiếp theo và quay lại bước 2.  Nếu không thì kết thúc.

Sơ đồ giải nén

Hình 14. Sơ đồ giải nén LZ78

Bắt đầu

Khởi tạo từ điển

Đọc một cặp (W, C) Ghi (.W + C) ra bản giải mã Cập nhật (.W + C) vào từ điển Còn kí tự trong bản mã? Kết thúc Đúng Sai

Ví dụ : Cho văn bản aaabbabaabaaabab. Quá trình nén TT Đoạn văn bản đã P C Từ điển W Ghi ra 1 a “” a 0 – “”, 1 – a 0 (0,a) 2 aaa a a 0 – “”, 1- a, 2 - aa 1 (1,a) 3 aaab “” b 0 – “”, 1- a, 2 – aa, 3- b 0 (0,b) (adsbygoogle = window.adsbygoogle || []).push({});

4 aaabba b a 0 – “”, 1- a, 2 – aa, 3 – b, 4 - ba 3 (3,a)

5 aaabbabaa ba a 0 – “”, 1- a, 2 – aa, 3 – b, 4 – ba,

5 – baa 4 (4,a)

6 aaabbabaabaaa baa a 0 – “”, 1- a, 2 – aa, 3 – b, 4 – ba,

5 – baa, 6 - baaa 5 (5,a)

7 aaabbabaabaaabab ba b 0 – “”, 1- a, 2 – aa, 3 – b, 4 – ba,

5 – baa, 6 – baaa, 7 - bab 4 (4,b)

Kết quả bản mã gồm các cặp sau: (0,a)(1,a)(0,b)(3,a)(4,a)(5,a)(4,b)

Quá trình giải nén

TT Cặp mã

đọc vào

Ghi

ra Từ điển Xâu kết quả

1 (0,a) a 0 – “”, 1 - a a

2 (1,a) aa 0 – “”, 1 – a, 2 – aa aaa

3 (0,b) b 0 – “”, 1 – a, 2 – aa, 3 – b aaab

4 (3,a) ba 0 – “”, 1 – a, 2 – aa, 3 – b, 4 - ba aaabba

5 (4,a) baa 0 – “”, 1 – a, 2 – aa, 3 – b, 4 – ba, 5 –

baa aaabbabaa

6 (5,a) baaa 0 – “”, 1 – a, 2 – aa, 3 – b, 4 – ba, 5 –

baa, 6 – baaa aaabbabaabaaa

7 (4,b) bab 0 – “”, 1 – a, 2 – aa, 3 – b, 4 – ba, 5 –

baa, 6 – baaa, 7 - bab aaabbabaabaaabab

2.4.4.3.Thuật toán LZW

LZW được đặt tên từ những người tạo ra nó A.Lempel, J.Ziv và Terry A.Welch.

Điểm khác biệt giữa LZ78 và LZW trong nguyên lý nén.

- Khởi tạo từ điển bao gồm tất cả các kí tự trong bảng chữ cái ban đầu. - Kí tự cuối cùng của đoạn copy này là kí tự đầu của đoạn copy sau. - Bản mã chỉ là chỉ số các đoạn copy chứ không có các kí tự nữa.

a. Quá trình nén

Thuật toán nén

Bước 1: Khởi tạo từ điển gồm các kí tự trong bảng chữ cái của văn bản xuất hiện trong văn bản đ ược đánh chỉ số từ 0. Xâu trung gian P rỗng. (adsbygoogle = window.adsbygoogle || []).push({});

Bước 2:Đọc kí tự tiếp theo trong văn bản vào C.

Bước 3: Xâu P + C đã có trong từ điển chưa?  Nếu có thì P ← P + C

 Nếu không thì:

i. Ghi ra bản mã chỉ số của P trong từ điển. ii. Thêm xâu P + C vào từ điển.

iii. P ← C (lúc này P chứa một kí tự). Bước 4: Còn kí tự nào trong văn bản không?

 Nếu có thì quay lại bước 2.  Nếu không thì:

i. Ghi ra bản mã chỉ số của P trong từ điển. ii. Kết thúc.

Sơ đồ nén

Hình 15. Sơ đồ nén LZW

Bắt đầu

Khởi tạo từ điển. Xâu trung gian P rỗng

Đọc kí tự tiếp theo vào C

P + C đã có trong từ điển?

P ← P + C

W ← chỉ số của P trong từ điển

Ghi ra bản mã W

Cập nhật P + C vào từ điển

P ← C

Còn kí tự trong văn bản?

W ← chỉ số của P trong từ điển

Kết thúc Ghi ra bản mã W Đúng Đúng Sai Sai

b. Quá trình giải nén

Gọi cW là từ mã đang được giải mã. Ký hiệu .cW là nội dung đoạn copy có ký hiệu cW trong từ điển.

Gọi pW là từ mã đứng trước từ mã hiện thời trong bản mã. Ký hiệu .pW là nội dung đoạn copy có ký hiệu pW trong từ điển.

Nguyên lý của giải mã như sau:

- Tại thời điểm khởi tạo thì từ điển giống như lúc mã hoá.

- Tại thời điểm bất kỳ trong quá khứ, khi từ điển chứa vài đoạn copy dài hơn.  Ghi nhớ từ mã trước pW.

 Đọc từ mã hiện thời cW từ bản mã.  Đưa ra đoạn copy .cW.

 Cộng đoạn copy .pW với kí tự đầu tiên của đoạn copy .cW và thêm vào từ điển.

Hai từ mã pW và cW liên tiếp nhau trong bản mã, khi đó kí tự cuối cùng của .pW là kí tự đầu tiên của .cW. (adsbygoogle = window.adsbygoogle || []).push({});

Chú ý: trong quá trình nén thuật toán thêm một đoạn copy vào từ điển trước khi toàn bộ đoạn đó được nén, đó là kí tự cuối của đoạn copy (được xử lý ở trong đoạn copy sau). Nếu vì một lý do nào đó mà trình nén sử dụng ngay lập tức đoạn copy này thì khi giải nén sẽ có vấn đề là gặp phải mã của một đoạn copy mà nó lại chưa xuất hiện trong từ điển (còn thiếu một kí tự cuối cùng là kí tự đầu tiên của đoạn copy được giải mã tiếp theo).

Ví dụ:

Giả sử đoạn copy IWOMBAT đã có trong từ điển với chỉ số là 300 (tức là mã của đoạn copy này là 300), còn đoạn copy IWOMBATI thì chưa có trong từ điển.

Khi gặp đoạn văn bản IWOMBATIWOMBATI trình nén sẽ đưa ra mã là 300 và thêm vào từ điển đoạn copy IWOMBATI, giả sử với mã là 400. Và sử dụng ngay mã 400 cho đoạn copy tiếp theo. Khi đó cả đoạn văn bản trên có mã là <300><400>.

Xét quá trình giải nén: sau khi thay <300> bằng đoạn copy IWOMBAT thì trình giải nén gặp mã <400>. Nhưng khi đó trong từ điển của trình giải nén chưa có đoạn copy IWOMBATI vì còn thiếu chữ I ở cuối.

Cho nên trong nguyên lý giải nén việc đưa ra đoạn copy .cW không phải lúc nào cũng thực hiện được. Tuy nhiên, nó cũng chỉ không thành côn g trong trường hợp gặp đoạn văn bản có dạng như trong ví dụ này. Vì để đưa ra đoạn copy của cW trong từ điển chúng ta cũng chỉ thiếu có một kí tự cuối và kí tự này xuất hiện ở đầu của đoạn copy .cW. Do đó, trong trường hợp này thì đoạn .pW được mở rộng bằn g thêm kí tự đầu tiên của nó, xâu kết quả được ra và thêm nó vào từ điển.

Thuật toán giải nén

Bước 1: Khởi tạo từ điển ban đầu gồm các kí tự trong bảng chữ cái của văn bản xuất hiện trong văn bản, được đánh chỉ số từ 0.

Bước 2: cW ← từ mã đầu tiên trong bả n mã.

Bước 3: Ghi đoạn copy .cW ra bản giải mã.

Bước 4: pW ← cW.

Bước 5: cW ← từ mã tiếp theo trong bản mã.

Bước 6: Đoạn copy .cW có trong từ điển không?  Nếu có thì

i. Ghi đoạn copy .cW ra bản giải mã.

ii. p ← .pW

iii. c ← kí tự đầu tiên của đoạn copy .cW iv. Thêm đoạn copy p + c vào từ điển.  Nếu không thì

i. p ← .pW

ii. c ← kí tự đầu tiên của đoạn copy .pW

iii. Ghi đoạn copy p + c ra bản giải mã và thêm nó vào từ điển.

Bước 7: Còn từ mã nào trong bản mã không?  Nếu có thì quay về bước 4.

 Nếu không thì kết thúc.

cW ← từ mã đầu tiên

Ghi .cW ra bản giải mã

cW ← từ mã tiếp theo

Ghi .cW ra bản giải mã p ← .pW

c ← kí tự đầu tiên của .pW

Ghi p + c ra bản giải mã

Cập nhật p + c vào từ điển Bắt đầu

Khởi tạo từ điển.

Đúng (adsbygoogle = window.adsbygoogle || []).push({});

Đúng pW ← cW

.cW đã có trong từ điển?

c ← kí tự đầu tiên của .cW

Cập nhật p + c vào từ điển Sai p ← .pW Còn kí tự trong văn bản? Sai

Ví dụ Cho văn bản aabababaaababb

Quá trình nén

TT Xâu đã xét P C Từ điển Ghi

ra

1 aa A a 0 – a, 1 – b, 2 - aa 0

2 aab A b 0 – a, 1 – b, 2 – aa, 3 - ab 0

3 aaba B a 0 – a, 1 – b, 2 – aa, 3 – ab, 4 - ba 1

4 aababa Ab a 0 – a, 1 – b, 2 – aa, 3 – ab, 4 – ba, 5 -

aba 3

5 aabababaa Aba a 0 – a, 1 – b, 2 – aa, 3 – ab, 4 – ba, 5 –

aba, 6 – abaa 5

6 aabababaaab Aa b 0 – a, 1 – b, 2 – aa, 3 – ab, 4 – ba, 5 –

aba, 6 – abaa, 7 – aab 2

7 aabababaaabab Ba b 0 – a, 1 – b, 2 – aa, 3 – ab, 4 – ba, 5 –

aba, 6 – abaa, 7 – aab, 8 – bab 4

8 aabababaaababb B b 0 – a, 1 – b, 2 – aa, 3 – ab, 4 – ba, 5 –

aba, 6 – abaa, 7 – aab, 8 – bab, 9 – bb 1

9 aabababaaababb 0 – a, 1 – b, 2 – aa, 3 – ab, 4 – ba, 5 –

aba, 6 – abaa, 7 – aab, 8 – bab, 9 – bb 1 Vậy bản mã là 001352411 Quá trình giải nén TT pW cW Từ điển Ghi ra 0 0 0 – a, 1 – b a 1 0 0 0 – a, 1 – b, 2 – aa a 2 0 1 0 – a, 1 – b, 2 – aa, 3 - ab b 3 1 3 0 – a, 1 – b, 2 – aa, 3 – ab, 4 – ba ab

4 3 5 0 – a, 1 – b, 2 – aa, 3 – ab, 4 – ba, 5 – aba Aba

6 2 4 0 – a, 1 – b, 2 – aa, 3 – ab, 4 – ba, 5 – aba, 6 –

abaa, 7 – aab Ba

7 4 1 0 – a, 1 – b, 2 – aa, 3 – ab, 4 – ba, 5 – aba, 6 –

abaa, 7 – aab, 8 – bab B

8 1 1 0 – a, 1 – b, 2 – aa, 3 – ab, 4 – ba, 5 – aba, 6 –

abaa, 7 – aab, 8 – bab, 9 - bb B (adsbygoogle = window.adsbygoogle || []).push({});

Kết quả thu đươc là aabababaaababb.

Một phần của tài liệu nén văn bản tiếng việt theo huffman (Trang 48)