1. Trang chủ
  2. » Công Nghệ Thông Tin

Mã Hoá Burrows Wheeler

7 1,5K 11

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 7
Dung lượng 47,5 KB

Nội dung

Có nhiều phương pháp mã hoá thông tin được sử dụng rộng rãi để đảm bảo tính chất an toàn, bảo mật dữ liệu. Bài viết này trình bày lời giải cho một đề thi tin học Quốc tế, nhưng nội dung của nó lại đề cập tới một cách tiếp cận mới trong kỹ thuật mã hóa và giải mã. Burrows Wheeler đề xuất phương pháp mã hoá thông tin như sau: ví dụ ta cần mã hoá từ BANANA, các bước tiến hành là: Bước 1: Từ cần mã hoá được dịch chuyển vòng tròn và tạo thành một ma trận LL ký tự, trong đó L là độ dài của từ. Ta có: BANANA ANANAB NANABA ANABAN NABANA ABANAN Bước 2: Sắp xếp lại các dòng của ma trận theo thứ tự từ điển: ABANAN ANABAN ANANAB BANANA NABANA NANABA Bước 3: Trích xâu từ các ký tự cuối ở mỗi dòng, thông báo xâu này và cho biết từ gốc là từ thứ mấy trong ma trận nhận được ở bước 2. Ta có (NNBAAA,4)

Trang 1

MÃ HOÁ BURROWS WHEELER Ngày nay, có nhiều phương pháp mã hoá thông tin được sử dụng rộng rãi để đảm bảo tính chất an toàn, bảo mật dữ liệu Bài viết này trình bày lời giải cho một đề thi tin học Quốc tế, nhưng nội dung của nó lại đề cập tới một cách tiếp cận mới trong kỹ thuật mã hóa và giải mã

Burrows Wheeler đề xuất phương pháp mã hoá thông tin như sau: ví

dụ ta cần mã hoá từ BANANA, các bước tiến hành là:

Bước 1: Từ cần mã hoá được dịch chuyển vòng tròn và tạo thành một ma trận L*L ký tự, trong đó L là độ dài của từ Ta có:

BANANA

ANANAB

NANABA

ANABAN

NABANA

ABANAN

Bước 2: Sắp xếp lại các dòng của ma trận theo thứ tự từ điển:

ABANAN

ANABAN

ANANAB

BANANA

NABANA

NANABA

Bước 3: Trích xâu từ các ký tự cuối ở mỗi dòng, thông báo xâu này và cho biết từ gốc là từ thứ mấy trong ma trận nhận được ở bước 2 Ta có (NNBAAA,4)

Yêu cầu: Hãy viết chương trình mã hoá và giải mã

Dữ liệu: Vào từ file CODE.INP, dòng đầu là một số 0 hoặc 1:

- Nếu là số 0 thì ta phải thực hiện thao tác mã hoá; và tiếp theo là một hoặc nhiều nhóm dòng, mỗi dòng là một xâu ký tự cần mã hóa

Dữ liệu ra bao gồm một hoặc nhiều nhóm hai dòng, dòng đầu là xâu ký tự đã

mã hoá, dòng tiếp theo là số nguyên dương cho biết vị trí từ gốc

- Nếu là số 1 thì ta phải thực hiện thao tác giải mã; và tiếp theo là một hoặc nhiều nhóm hai dòng, dòng đầu là xâu ký tự đã mã hoá, dòng tiếp theo là số nguyên dương cho biết vị trí từ gốc

Dữ liệu ra bao gồm một hoặc nhiều nhóm dòng, mỗi dòng là một xâu ký tự

đã giải mã

Trang 2

Ví dụ 1:

CODE.INP

0

BANANA

COGUMELO

RONALDO

CODE.OUT

NNBAAA

4

OMOEULCG

1

NLAORDO

7

Ví dụ 2:

CODE.INP

1

NNBAAA

4

OMOEULCG

1

NLAORDO

7

CODE.OUT

BANANA

COGUMELO

RONALDO

Cho biết các xâu có thể có độ dài tới 1000 ký tự (L≤1000)

Dễ thấy rằng, với bài toán này chúng ta cần tìm ra một thuật giải và cấu trúc dữ liệu phù hợp nếu không sẽ không thể giải được với dữ liệu đầu bài cho khá lớn như vậy Chẳng hạn, ta không thể khai báo một mảng A:array[1 1000,1 1000] để chứa mảng ký tự do hạn chế về miền nhớ dành cho biến tĩnh của ngôn ngữ lập trình Pascal Chúng ta sẽ cùng phân tích để tìm lời giải tối ưu cho bài toán

Để có thể mã hoá, ta cần phải biết được các ký tự cuối của các từ (và đương nhiên là phải biết vị trí từ gốc); vì các từ được dịch chuyển vòng tròn

Trang 3

nên nếu ta có thể có một "mảng vòng tròn" để lưu các xâu và một mảng chỉ

số để lưu vị trí bắt đầu của các xâu thì sẽ tiết kiệm đáng kể chi phí về miền nhớ Để tạo ra mảng vòng tròn như vậy, ta coi một mảng một chiều như là mảng vòng tròn với lưu ý là phần tử ở cuối mảng được coi như đi trước phần

tử đầu tiên Với ví dụ đầu bài ta có mảng chứa xâu và mảng chỉ số của các xâu được chuyển vòng tròn là:

Dựa vào hai mảng này ta dễ dàng xác định được các xâu sau khi dịch chuyển với lưu ý là ký tự ở vị trí cuối cùng đi trước ký tự đầu tiên Ví dụ: xâu thứ 2 (bắt đầu từ vị trí thứ hai trong mảng chỉ số) là: ANANAB, xâu thứ 5 (bắt đầu từ vị trí thứ 5 trong mảng chỉ số) là: NABANA Việc sắp xếp các xâu thực chất ta chỉ làm việc trên hai mảng này Sau khi sắp xếp các xâu theo thứ tự từ điển, mảng chỉ số có dạng:

Mảng này cho ta biết vị trí các xâu sau khi sắp xếp, xâu thứ nhất (xâu BANANA) ở vị 4, xâu xâu thứ 2 (xâu ANANAB) ở vị trí 3…Từ đó, chúng ta

dễ dàng suy ra xâu mã hoá bằng cách trích ra các ký tự ở vị trí ngay trước của xâu tương ứng Cụ thể như sau: Lấy ký tự trước vị trí đầu tiên của xâu 6: do xâu 6 bắt đầu từ vị trí 6 nên ta lấy ký tự ở vị trí 5 của mảng ban đầu, là ký tự

N Lấy ký tự trước vị trí đầu tiên của xâu 4: do xâu 4 bắt đầu từ vị trí 4 nên ta lấy ký tự ở vị trí 3 của mảng ban đầu, là ký tự N Cứ như vậy, ta thu được xâu kết quả là: NNBAAA

Công việc còn lại là đi tìm thuật toán để giải mã hiệu quả Để có thể giải mã, ta cần biết xâu mã hoá s và vị trí n của xâu gốc Thuật toán được đưa

ra như sau:

- Sắp xếp các từ trong s theo thứ tự từ điển để thu được xâu s', phải đảm bảo giữ nguyên thứ tự của các từ giống nhau trong xâu s (nên dùng phương pháp sắp xếp nổi bọt) Ví dụ với s=NNBAAA thì s'=AAABNN

-Bắt đầu từ vị trí thứ n trong xâu s' và tiến hành duyệt lần lượt trên hai xâu để thu được kết quả Cụ thể: ký tự đầu tiên ở vị trí n=4 của s', là B; tiếp theo vì

B ở vị trí thứ 3 trong s nên ký tự thứ hai ở vị trí 3 trong s', là A; tiếp theo vì A

ở vị trí thứ 6 trong s nên ký tự thứ ba ở vị trí 6 trong s', là N…cứ như vậy ta thu được kết quả là BANANA

Trang 4

Lưu ý: nếu phương pháp sắp xếp không đảm bảo giữ nguyên thứ tự của các

từ trong xâu gốc thì có thể dẫn đến một số test bị sai Chẳng hạn, bạn đọc có thể tự kiểm tra khẳng định này để thấy rằng nếu giải mã xâu (NPMAAA, 6) thì có thể sẽ cho PAMANA nhưng đáp án đúng phải là PANAMA Trong ví

dụ minh hoạ ở trên, các ký tự A tại vị trí 4, 5 và 6 của xâu s=NNBAAA phải tương ứng với các ký tự A tại các vị trí 1, 2 và 3

Toàn văn chương trình như sau:

program bw;{chuong trinh ma hoa va giai ma Burrows Wheeler}

var i,j,n:integer;

fi,fo:text;

a,c:array[1 1000] of char;

b:array[1 1000] of integer;

function lessthan(i,j,n:integer):boolean;

{kiem tra xau a tai vi tri i co lon hon taij vi tri j ko

do dai xau la n=length(a), tinh theo modulo}

var ii:integer;

begin

ii:=0;

while (ii<n)and (a[i]=a[j]) do

begin

inc(ii);

if i=n then i:=1 else inc(i);

if j=n then j:=1 else inc(j);

end;

lessthan:= a[i]<a[j];

end;

function eq(i,j,n:integer):boolean;

{kiem tra xau a tai vi tri i co bang xau tai vi tri j ko

do dai xau la n=length(a), tinh theo modulo}

var ok:boolean;ii:integer;

begin

ok:=true;

ii:=0;

while (ii<n)and(ok) do

begin

inc(ii);

Trang 5

if a[i]<>a[j] then ok:=false;

if i=n then i:=1 else inc(i);

if j=n then j:=1 else inc(j); end;

eq:=ok

end;

procedure code(n:integer;var m:integer); var k,i,tg,j:integer;

begin

m:=0;

for i:=1 to n do b[i]:=i;

for i:=1 to n-1 do

for j:=1+i to n do

if lessthan(b[j],b[i],n)then

begin

tg:=b[i];

b[i]:=b[j];

b[j]:=tg;

end;

for j:=1 to n do

if m=0 then if eq(1,b[j],n)then m:=j; end;

procedure decode(n,m:integer);

{N:vi tri cua xau ban dau trong day da xs M:chieu dai xau}

var i,j,k:integer;tg:char;

begin c:=a;

for i:=1 to m do b[i]:=i;

for i:=1 to m-1 do

for j:=m downto i+1 do

if c[j]<c[j-1] then

begin

tg:=c[j-1];

c[J-1]:=c[j];

c[j]:=tg;

k:=b[j-1];

Trang 6

b[j-1]:=b[j];

b[j]:=k;

end;

i:=1;k:=n;write(fo,c[k]);

while i<m do

begin

k:=b[k];

write(fo,c[k]);

inc(i);

end;

writeln(fo);

end;

procedure solve;

var I,c,j:integer;

begin

assign(fi,'code.inp');

reset(fi);

assign(fo,'code.out');

rewrite(fo);

readln(fi,c);{c=0:ma hoa; c=1:giai ma}

if c=0 then

while not eof(fi) do

begin

i:=0;

while not eoln(fi) do

begin

inc(i);

read(fi,a[i]);

end;

readln(fi);

code(i,n);

for j:=1 to i do

if b[j]=1 then write(fo,a[i]) else write(fo,a[b[j]-1]); writeln(fo);

writeln(fo,n);

Trang 7

end

else

while not eof(fi) do

begin

i:=0;

while not eoln(fi) do begin

inc(i);

read(fi,a[i]); end;

readln(fi);

readln(fi,n);

decode(n,i);

end;

close(fi);close(fo);

end;

begin

solve;

end.

Ngày đăng: 20/06/2014, 11:06

TỪ KHÓA LIÊN QUAN

w