Khi đọc xong phần tử cuối cùng của một tệp thì tệp đó chuyển sang trạng thái kết thúc (EOF), do đó nếu ta tổ chức vòng lặp WHILE trong thủ tục trộn hai tệp theo điều kiện (NOT EOF(f)) [r]
(1)MỤC LỤC
Trộn tệp
Bài 2: Xếp ba lơ sách lập trình sáng tạo
Lớp 11:
(2)Trộn tệp
Bài 5.5 Trộn hai tệp – Tr150 Nguyễn Xuân Huy – Sáng tạo thuật tốn lập trình Cho hai tệp văn data1.inp data2.inp chứa số nguyên tăng Viết chương trình trộn hai dãy liệu hai tệp thành dãy liệu tăng nhất ghi tệp văn data.out
Chú ý:
- Với liệu cho tệp thứ số, tệp thứ hai số tệp kết chứa 11 số
- Số lượng số tệp tối đa 50 nghìn khơng biết trước
- Các số có giá trị kiểu nguyên, tách dấu cách nằm nhiều dịng - Khi trộn hai tệp nói ta phải thực tối thiểu 22 lần đọc-ghi bao gồm 11 lần đọc 11 lần ghi
Bộ Test 1
Bộ test 2
data1.inp 2 3 5 5 10 data2.inp 3 3 4 7 12 20 data.out 2 3 3 3 4 5 5 7 10 12 20 data1.inp 2 4 8 15 data2.inp 3 3 4 18 22 30 35 data.out 2 3 3 4 4 8 15 18 22 30 35 Thuật toán
Ta dùng phương pháp cân Gọi hai tệp chứa liệu cần trộn f và g, tệp chứa kết trộn h Hãy tưởng tượng, ta dùng tay trái lấy lần lượt, lần phần tử tệp f (ghi vào biến t) dùng tay phải lấy lần phần tử tệp g (ghi vào biến p) So sánh vật nặng hai tay t và p Tay cầm phần tử nhẹ đặt phần tử vào tệp kết h và do tay rỗi nên lấy tiếp phần tử từ tệp tương ứng Quá trình kết thúc hai tệp f hoặc g duyệt xong Cuối ta chuyển nốt phần tử lại tệp chưa duyệt hết (tệp f hoặc g) vào tệp kết h
Ta cần lưu ý điểm sau đây:
(3)dùng biến lôgic ef ghi nhận trạng thái hết tệp f sớm nhịp Điều có nghĩa ef=FALSE biến t vẫn chứa giá trị chưa xử lí (chưa so sánh với p và chưa ghi vào tệp h) Chú ý dù ef = FALSE ta có EOF(f)=TRUE Một biến eg tương tự tạo cho tệp g Về chất hiểu biến ef eg chúng nhận giá trị TRUE thực đọc đơn vị liệu từ file
(* Pascal *)
(* - CÁCH Merge Files
-*) program MergeFiles; uses crt;
const
BL = #32; MN = 12;
fn = 'data1.inp'; gn = 'data2.inp'; hn = 'data.out';
{ - Tron tep fn va gn ghi vao hn -} procedure FMerge;
var
f,g,h: text; ef, eg: Boolean; t, p: integer;
d: longint; {so phan tu tep out} begin
assign(f,fn); reset(f); assign(g,gn); reset(g); assign(h,hn); rewrite(h); ef := SeekEof(f);
if NOT eof then read(f,t); eg := SeekEof(g);
if NOT eg then read(g,p); d := 0;
while (NOT ef) AND (NOT eg) if t < p then
begin inc(d);
write(h,t,BL);
if d mod 10 = then writeln(h); ef := SeekEof(f);
if NOT ef then read(f,t); end
else begin
(4)write(h,p,BL);
if d mod 10 = then writeln(h); eg := SeekEof(g);
if NOT eg then read(g,p); end;
while (NOT ef) begin
inc(d);
write(h,t,BL);
if d mod 10 = then writeln(h); ef := SeekEof(f);
if NOT ef then read(f,t); end;
while (NOT eg) begin
inc(d);
write(h,p,BL);
if d mod 10 = then writeln(p); eg := SeekEof(g);
if NOT eg then read(g,p); end;
close(f); close(g); close(h); end;
BEGIN
FMerge; END.
{ -CÁCH -}
Đọc liệu từ tệp f vào biến t tệp g vào biến p
Trường hợp tệp phần tử: So sánh giá trị t p Giá trị nhỏ (giả sử biến t) đặt (ghi) vào tệp h Sau biến t chứa giá trị tệp f Tiếp tục so sánh giá trị t&p hết phần tử tệp => thóat khỏi vịng lặp Ví dụ test Khi đọc đến giá trị 10, cuối file => vòng lặp thóat Lúc đó, số 12 biến p chưa ghi vào tệp h.
Để ghi số 12 vào tệp h trước kết thúc vòng lặp, cần phải có câu lệnh: Nếu trái(t) đến cuối file ghi giá trị phải(p) vào h, ngược lại ghi giá trị trái (t) vào tệp h. Nếu tệp có số lượng phần tử, đến chương trình chấm dứt Nhưng số lượng phần tử tệp có độ dài khác nhau, test trên, phải xét trường hợp
Trường hợp có tệp phần tử: Phải ghi phần tử lại vào tệp h Ví dụ test sau khỏi vịg lặp cịn 20 (test1) 22, 30, 35 (test 2): Chừng chưa đến cuối tệp f đọc ghi giá trị vào h ; Chừng chưa đến cuối tệp g thì đọc ghi giá trị vào h ;
(5)assign(f,'data1.txt'); reset(f); assign(g,'data2.txt'); reset(g); assign(h,'data.txt'); rewrite(h); end;
procedure xuly; var t,p,d,ts,ps:integer; begin
read(f,t); read(g,p);
while (not eof(f))and( not eof(g) )do begin
if p<t then begin
writeln(h,p); read(g,p); end
else begin
writeln(h,t); read(f,t); end;
if eof(f) then writeln(h,p); if eof(g) then writeln(h,t); end;
while not eof (f) begin
readln(f,t); writeln(h,t); end;
while not eof(g) begin
readln (g,p); writeln(h,p); end;
end; BEGIN mo; xuly;
close(f); close(g); close(h); END.
Bài 2: Xếp ba lơ sách lập trình sáng tạo var a,b,t,h,x:array[1 100] of integer;
(6)procedure modoc; var i:integer; begin
assign(f,'balo.inp'); reset(f);
readln(f,n,m); for i:=1 to n begin
readln(f,a[i],b[i]); h[i]:=i;
x[i]:=b[i]; end;
{a: mang luu luong cua cac vat b: don gia cua moi vat
h: chi so cua moi vat} end;
procedure moghi; begin
assign(g,'balo.out'); rewrite(g);
end;
procedure traodoi(var p,q:integer); var tam:integer;
begin tam:=p; p:=q; q:=tam; end;
procedure xuli; var i,j:integer; begin
for i:=1 to n-1 for j:=i+1 to n if b[i]<b[j] then begin
traodoi(b[i],b[j]); traodoi(a[i],a[j]); traodoi(h[i],h[j]); end;
tong:=0; tien:=0; i:=1;
while (tong<m)and(i<=n) begin
tong:=tong+a[i]; t[h[i]]:=a[i];
(7)tien:=tien+a[i]*b[i];
{so tien chon den vat thu i (i duoc tinh tren bang b)} inc(i);
end; i:=i-1;
if tong>m then begin
t[h[i]]:=t[h[i]]-(tong-m);
{so luong vat co chi so la h[i] duoc chon de tong=m} tien:=tien-b[i]*(tong-m);
{so tien cuoi cung} end;
for i:=1 to n writeln(g,t[i]); write(g,tien);
end; BEGIN modoc; moghi; xuli;
close(f); close(g); END
= = = = = = = = = = = = = = = = =
Lớp 11: Cần 11b3, Huy 11b7, Nhàn 11b8, Nguyên 11b1, Kế 11b6, Hùng 11b7, Chiến 11b6, Tuyền 11b6
Buổi thứ 1: Kiến thức chung mảng (Hằng dạy)
Buổi thứ (19/2/2012): Củng cố kiến thức mảng chiều Mảng:
Viết chương trình nhập vào N phần tử cho trước Tính tổng số có dãy
2 Tính tổng số chia hết cho Đếm số có giá trị
Tìm dãy lớn
Bài 4: Đưa số phần tử dãy lớn có mảng Dãy lớn dãy gồm phần tử liên tiếp tăng Ví dụ dãy A: Kết quả: Độ dài dãy lớn 3, dãy có dãy (2,4); (1,5,8); (7,9)
Hướng dẫn
Đối với 1-3, học sinh tự làm Riêng
Tư tưởng: Bộ test đưa vào phải dãy đầu dãy, dãy cuối dãy Test1:
Test2: 5
Test3:
Test4:
Test5: Test6:
So sánh ai-1(2)< ai(4) đếm tăng lên 1, ai-1(4)>ai(1) đếm lại từ đầu (dem=0). Biến dmax để lưu giá trị dãy tăng, thay đổi dmax dmax<dem
(8)Biến để lưu vết phần tử đưa vào mảng kết h, (ví dụ biến k)
Biến xác B định K đầu dãy dãy khơng có trường hợp a[i-1]>a[i] (B=0), có 01 lần a[i-1]>a[i] (B=1) K khơng đầu dãy (B>1)
Muốn in dãy tăng đó, ta cần lưu dãy tăng vào mảng h In giá trị mảng h từ đến dmax.
Chương trình minh họa
Program dem_day_tang;{ chỉnh sửa lại chương trình cho với test dãy cuối dãy}
var dem,dmax,n,i:byte; a:array [1 20] of byte; begin
write('Nhap so phan tu cua mang: '); readln(n);
for i:=1 to n begin
write('Nhap phan tu thu ',i,': '); readln(a[i]);
end;
For i:=2 to n
if a[i-1]<a[i] then dem:=dem+1 else
begin
if dmax<dem then dmax:=dem; dem:=0; end;
writeln('= = = = = = = = = = = = = = = = = = = = = = = = = = = = '); writeln('Day vua nhap vao la: ');
writeln('N= ',n); write('A: ');
for i:=1 to n write(a[i]:3); writeln;
writeln('day lon nhat gom co: ',dmax+1,' phan tu'); readln
end
-program dem&indaycontang;
VAR N,I,J,Dem,DMax,PhantuDau, PhantuCuoi:BYTE; A:ARRAY[1 250] OF INTEGER;
BEGIN
write('Moi ban nhap kich thuoc cua day:');readln(N); Writeln('Moi ban nhap gia tri cac phan tu cua day'); FOR i:=1 TO N DO
(9)DMax:=0; dem:=0; FOR i:=1 TO N DO BEGIN
dem:=0; j:=i;
WHILE (a[j]<=a[j+1]) AND (j<n) DO BEGIN
dem:=dem+1; j:=j+1;
END;
IF DMax<dem THEN BEGIN
DMax:=dem;
PhantuDau:=i; PhantuCuoi:=j; END;
END;
writeln('Day tang lon nhat la:'); FOR i:=PhantuDau TO PhantuCuoi DO Write(A[i],' ');
readln END
= = = = = = = = = = = = = = = = = = = = = Program dem&indaycon2_de_hieu;
VAR f,g:text;
a,h:array[1 100] of integer; n,max,k:integer;
procedure modoc; var i:integer; begin
assign(f,'day.inp'); reset(f);
i:=1;
while not eof(f) begin
read(f,a[i]);
if eof(f) then break; i:=i+1;
end; n:=i; end;
procedure moghi; begin
(10)rewrite(g); end;
procedure xuly; var i,j,d:integer; begin
i:=1; k:=1; max:=0; d:=0;
while i<=n begin
if a[i]<a[i+1] then d:=d+1
else
if d+1>max then begin
max:=d+1;
for j:=1 to max {luu cac gia tri cua day tang vao mang h} begin
h[j]:=a[k]; k:=k+1; end; d:=0; end; i:=i+1; end;
writeln(g,max); for j:=1 to max-1 write(g,h[j],' '); write(g,h[max]); end;
BEGIN modoc; moghi; xuly; close(f); close(g); END
=- - - - - =
Program dem_day_tang; {quan biet luu vet k (danh dau phan tu nao da luu vao mang kq h}
var b,dem,dmax,n,k,j,i:byte;{b: de luu so lan a[i-1]>a[i]}
a,h:array [1 20] of byte; {mang a:mang nguon; h:mang kqua}
(11)writeln('======== DEM VA DUA RA DAY CON LON NHAT========'); assign(f,'day1.inp'); {lay du lieu tu tep}
reset(f); i:=1;
while not eof(f)
begin {tao tep chua cac so de doc vao mang A, khoi mat cong nhap tung phan tu =>test cho nhanh}
read(f,a[i]); if eof(f) then break; i:=i+1; end; n:=i; close(f);
{write('Nhap so phan tu cua mang: ');{nhap du lieu tung phan tu bang phim} {readln(n);}
for i:=1 to n begin
write('Nhap phan tu thu ',i,': '); readln(a[i]);
end;}
K:=1; {vet o vi tri dau tien} b:=0; {chua xay a[i-1]<a[i]} For i:=2 to n
if a[i-1]<a[i] then dem:=dem+1 else
begin
b:=1; {da xay 01 lan a[i-1]>a[i]} if dmax<dem then
begin
dmax:=dem+1;
for j:=1 to dmax do{luu cac phan tu vao mang kq h} begin
h[j]:=a[k];
k:=k+1;{k da dich chuyen >1 vi tri}
b:=b+1;{danh dau hon phan tu luu vao mang kq h} end;
end; dem:=0; end;
if dmax<=dem then begin
(12)if (k=1){k dang o vi tri dau tien} and (b=0){ko co a[i-1]>a[i]} then {day a:1, 2, lien tiep tang}
for j:=1 to dmax {bien k dung luu vet chua dich chuyen(b=0)} begin
h[j]:=a[k]; k:=k+1; end;
{ for j:=1 to dmax } {truong hop k chua dich chuyen nhung da co su} { begin } {so sanh giua phan tu lien ke a[i-1]>a[i]}
if (k=1) and (b=1) then {test: } for j:=1 to dmax
begin k:=k+1; h[j]:=a[k]; end;
if (k>1) and(b>1) then {k o vtri >2: co > 1ptu luu vao mang kq h} for j:=1 to dmax
begin
h[j]:=a[k]; k:=k+1; end; { end; } end;
writeln('= = = = = = = = = = = = = = = = = = = = = = = = = = = = '); writeln('Day vua nhap vao la: ');
writeln('N= ',n); write('A: ');
for i:=1 to n write(a[i]:3); writeln;
writeln('day lon nhat gom co: ',dmax,' phan tu'); write('Day con: ');
for j:=1 to dmax write(h[j]:3);