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

Thuật toán lưu dữ liệu

6 872 5
Tài liệu đã được kiểm tra trùng lặp

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Một cách lưu dữ liệu mới
Tác giả Đặng Thanh Tùng
Trường học Trường Đại Học Bách Khoa Hà Nội
Thể loại bài viết
Năm xuất bản 2004
Thành phố Hà Nội
Định dạng
Số trang 6
Dung lượng 34,5 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Thuật toán lưu dữ liệu

Trang 1

Một cách lưu dữ liệu mới

Đặng Thanh Tùng

Các bạn thân mến!

Sau khi đọc số báo tháng 7 năm 2004 tôi đã rút ra một phương pháp mới về việc lưu dữ liệu Như các bạn đã biết, với những bài toán có dữ liệu lớn chúng ta được phép dùng bộ nhớ ảo (Virtual memory) để giải nhưng địa chỉ lưu được tối đa là khoảng 200K byte (Để máy tính nào cũng chạy được) nhưng như thế chưa tận dụng được khoảng trống trong máy của chúng ta Vì vậy trong bài viết này tôi xin được trình bày một phương pháp khác có thể tận dụng tối đa bộ nhớ của máy tính.

Đặt vấn đề:

Trong thực tế việc tìm đường đôi khi rất khó khăn bởi việc mã hoá thành các đỉnh của đồ thị và giả sử có mã hoá được thì số đỉnh tồn tại cũng rất lớn Vấn đề nảy sinh về việc lưu trữ hết các đỉnh Các bạn có để ý rằng trong pascal có thể đọc file và lấy dữ liệu từ đó ra rất

dễ dàng! Chính vì thế mà tôi đã tận dụng "lỗ hổng" này của pascal để xử lý dữ liệu.

Bắt đầu từ bài toán quen thuộc: Cho đồ thị: gồm N đỉnh, đỉnh xuất phát và đỉnh đích hãy

tìm đường đi ngắn nhất từ đỉnh xuất phát tới đỉnh đích (n<=500000 đỉnh!)

Dữ liệu vào từ file "loang.inp" trong đó

- Dòng đầu tiên bao gồm: số N đầu tiên thể hiện số đỉnh của đồ thị, hai số tiếp theo lần lượt

là đỉnh xuất phát và đỉnh đích

- Những dòng còn lại là một cặp (u,v) thể hiện từ u đến được v

Kết quả ghi ra file "loang.Out":

- Dòng đầu tiên là số m thể hiện số bước đi ngắn nhất

- M dòng sau thể hiện cho mỗi đỉnh trong đường đi

Cũng với thuật toán duyệt đồ thị theo chiều rộng mà ta có thể giải bài này hết sức dễ dàng với việc lưu dữ liệu tôi trình bày dưới đây Như các bạn đã biết với N<=500 000 đỉnh thì việc dùng mảng là không thể mà file là kho chứa dữ liệu vô tận mà ta còn chưa biết hết Việc giải bài này phụ thuộc vào điều đó

Thuật giải:

Các bạn hãy để ý rằng mỗi đỉnh nếu chuyển thành một xâu thì sẽ là một xâu có độ dài không quá 8 ký tự và ta sẽ lợi dụng điều đó để giải quyết bài toán này:

Chuyển tất cả các đỉnh cũng như đầu và cuối (trong loang) thành một xâu từ đó chuyển thành một file text để lưu những gì có liên quan tới nó

VD: Đỉnh 3 có thể đến được đỉnh 1 và đỉnh 2 Khi đó

File "3.ke" sẽ lưu trữ 2 số 1 và 2:

3.ke

1

2

Mục đích của mỗi file *.ke là để lưu giữ các đỉnh có thể đến được từ đỉnh *.queue

Tương tự với các file khác

*.đ: chứa một số 1 hoặc 0 thể hiện đỉnh * đã bị đánh dấu hay chưa

*.tr: chứa một số nguyên thể hiện là đỉnh trước nó

Trang 2

Quan trọng nhất của bài toán này là xử lý mảng Queue.

Bình thường đoạn chương trình loang như sau:

Repeat

U:=queue[dau];

Inc(dau);

For v:= 1 to n do

If (tu u den v) and (v chua bi danh dau) then

Begin

Dan dau (v);

Inc(cuoi):=v;

Tr[v]:=u;

End;

Until dau>cuoi;

Ta sẽ thay phần tử queue[dau] (cũng như queue[cuoi]) bằng cách chuyển dau(hay cuoi) thành một file là "dau.que" để lưu v như sau:

Inc(cuoi);

Str(cuoi,temp);

Assign(f,temp+ ’.que’);

Rewrite(f);

Writeln(f,v);

Close(f);

Với cách đó bạn có thể lưu được rất nhiều đỉnh mà không cần quan tâm đến độ lớn của v (hay dau hoặc cuoi)

Toàn bộ chương trình của bài toán này như sau:

{$A+, B-, D+, E+, F-, G-, I+, L+, N-, O-,P-,Q+,R+,S+,T-,V+,X+}

{$M 16384,0,655360}

USES crt;

Const fi= ’loang.in’;

Fo= ’loang.out’;

Ke= ’.ke’;

Que= ’.que’;

đ = ’.đ’;

tr = ’.tr’;

kq = ’.kq’;

Var n,xp,di:longint;

Time:longint;

Procedure readf;

Var f,f1: text;

U,v: string;

Begin

Assign(f,fi);

Reset(f);

Readln(f,n,xp,di);

For u:=1 to n do

Trang 3

Str(u,temp);

Assign(f1,temp+ke); Rewrite(f1);

Close(f1);

End;

While not seekeof(f) do Begin

Readln(f,u,v);

Str(u,temp);

Assign(f1, temp+ke); Appent(f1);

Writeln(f1,v);

Close(f1);

Assign(f1, temp+đ); rewrite(f1);

Writeln(f1,0);

Close(f1);

Str(v,temp);

Assign(f1,temp+đ); Rewrite(f1,0);

Close(f1);

End;

Close(f);

End;

Procedure Loang; Var d,c:longint;

U,v:longint;

Te1,te2: string;

Te3: sting;

F,f1,f2,f3: text;

Ok: byte;

Begin

D:=1; c:=1;

Str(xp,te1);

Assign(f, te1+đ); Rewrite(f);

Writeln(f,1);

Close(f);

Assign(f,te1+tr); Rewrite(f,0);

Trang 4

Assign(f, ’1’ +que);

Rewrite(f);

Writeln(f,xp);

Close(f);

Repeat

Str(d,te1);

Assign(f,tel+que);

Reset(f);

Readln(f,u); {lay phan tu dau tien trong "queue"} Close(f);

Inc(d);

Str(u,te1);

Assign(f,te1+ke); {Doc cac phan tu ke voi u}

Reset(f);

While not seekeof(f) do

Begin

Readln(f,v);

Str(v,te2);

Assign(f1,te2+đ);

Reset(f1);

Readln(f1,ok); {kiem tr xem v da bi danh dau hay chua}

If ok=0 then

Begin

Assign(f2, te2+đ);

Rewrite(f2); {Danh dau v}

Write(f2,1);

Close(f2);

Inc(c);

Str(c, te3);

Assign(f2, te3+que);

Rewrite(f2); {Nhap v vao "queue"}

Writeln(f2,v);

Close(f2);

Assign(f2,te2+tr);

Rewrite(f2,u); {luu lai truoc cua v}

Close(f2);

End;

Close(f1);

End;

Close(f);

Trang 5

Until d>c;

End;

Procedure lankq;

Var sb, ok, t,i:longint;

Temp: string;

F,f1:text;

Begin

Assign(f,fo);

Rewrite(f);

Str(di,temp);

Assign(f1,temp+đ);

Reset(f1);

Readln(f1,ok);

Close(f1);

If ok=0 then

Writeln(f, ’Khong ton tai duong di’)

Else

Begin

Sb:=0;

Repeat

Inc(sb);

Str(sb, temp);

Assign(f1,temp+kq); {ghi dich vao file ket qua tam thoi}

Readln(f1,t);

Close(f1);

Di:=t;

Until di=0;

Writeln(f,sb);

For i:=sb downto 1 do

Begin

Str(i,temp);

Assign(f1,temp+kq); {Doc lai cac file ket qua de chuyen sang file can ghi} Reset(f1);

Readln(f1,t);

Close(f1);

Writeln(f,t);

End;

End;

Close(f);

End;

Begin

Time:=MemL[0:$46C];

Docf;

Trang 6

Lankq;

Writeln((MemL[0:$46C] - time)/18.2:10:10);

End

Trên đây chỉ là một thủ thuật nhỏ để lưu dữ liệu mà từ đó các bạn có thể tận dụng cho mình Tôi xin lưu ý đây chỉ là một thủ thuật cho nên các bạn hãy dùng cho đúng lúc, đúng chỗ Chương trình trên mới chỉ làm được với đồ thị có hướng Các bạn có thể dễ dàng cải tiến lại chút ít để có thể làm được hai chiều (phần đọc file!) Nếu có ý kiến đóng góp mời

các bạn gửi đến hòm thư hocpascal@yahoo.com Chúc các bạn thành công!

Ngày đăng: 11/09/2012, 15:00

TỪ KHÓA LIÊN QUAN

w