SKKN - Mt s dng bi tp lp trỡnh Pascal cú d liu kiu tp vn dng kin thc mng
A. Đặt vấn đề :
Hiện nay máy tính đang đợc sử dụng rộng rãi trong các cơ quan và gia đình.Nó
là một công cụ hữu hiệu giúp cho công việc nhanh hơn dễ dàng hơn. Học sinh đang
học tập tin học trong nhà trờng. Có nhiều cuộc thi tổ chức cho học sinh giỏi tin học ,
trong đó có cuộc thi tin học trẻ không chuyên.Thi thực hành lập trình bằng ngôn ngữ
Pascal là một phần thi hay và khó.
PASCAL là ngôn ngữ lập trình bậc cao của tác giả Niklaus Wirth (giáo s ngời
Thuỵ sĩ), đợc công bố vào đầu những năm 1970. Tên PASCAL là để kỉ niệm nhà Toán học
ngời Pháp B. Pascal.
Là ngôn ngữ lập trình có tính cấu trúc và tính hệ thống: các kiểu dữ liệu đa dạng,
các cấu trúc điều khiển chặt chẽ, các cấu trúc khối trong chơng trình rõ ràng,các đại lợng
(biến và hằng) đã đợc khai báo để sử dụng với kiểu dữ liệu này thì không thể đem dùng
lẫn với kiểu khác.
PASCAL ban đầu đợc sáng tác để làm ngôn ngữ dạy học cho những ngời mới học lập
trình. Có tính sáng sủa, dễ hiểu, dễ đọc của nó giúp ngời mới học có thể viết một chơng
trình máy tính một cách dễ dàng.
Hoc sinh thờng gặp khó khăn ở phần này vì bài tập đa dạng và khó. Đa số những bài
tập ra theo kiểu tệp ứng dụng thực tế nên học sinh còn lúng túng để đa về dạng bài
toán cơ bản, cha tìm đợc thuật toán phù hợp. Để giúp học sinh hiểu rõ hơn cách làm
bài Pascal khi thi tin học không chuyên tôi đã đa ra kinh nghiệm một số dạng bài
tập lập trình Pascal có dữ liệu kiểu tệp vận dụng kiến thức mảng .Có nhiều dạng
bài tập nhng tôi chủ yếu đa ra bài tệp kiểu tệp vận dụng kiến thức mảng 1 chiều, mảng
2 chiều.
B. giảI quyết vấn đề:
I,D LIU KIU TP
1, Khỏi nim:
Khi gii cỏc bi toỏn cn s dng nhiu ln v sau thỡ ta phi t chc d liu lu tr
trờn a (d liu kiu tp).
Cỏc s liu c gừ vo lu trờn mt tp nh vn bn.Kt qu cng c lu trờn mt
tp vn bn khỏc .Khi kt thỳc chng trỡnh hoc tt mỏy thỡ d liu kiu tp vn tn
Cú pháp:
Write(FileVar, Item1, Item2, , ItemN);
Ví dụ: Ta cần ghi vào tệp ChuCai.txt các giá trị 1 5, thực hiện như sau:
Assign(F1, ’ChuCai.txt’);
ReWrite(F1); {mở tệp}
For a:= 1 to 5 do Write(F1, a);
Close(F); {khi ghi xong phải đóng tệp thì dữ liệu mới được lưu vào tệp}
End.
c. Đọc dữ liệu từ một tệp đã có :
Một chương trình muốn sử dụng các dữ liệu đã được chứa trong một têp, đầu tiên phải
mở tệp đó ra để đọc, thủ tục sau nhằm mở một đọc:
Cú pháp:
Assign(FileVar, FileName);
Reset(FileVar);
Tống Trần Hướng
2
SKKN - Mt s dng bi tp lp trỡnh Pascal cú d liu kiu tp vn dng kin thc mng
Sau lnh Reset, nu tp khụng rng thỡ ca s tp bao gi cng tr vo phn t u
tiờn ca tp v chng trỡnh s sao chộp phn t ca tp c tr sang bin m ca
s. Nu ta m mt tp cha tn ti trờn a thỡ s cú li.
c d liu t tp, ta dựng th tc READ dng sau:
Read(FileVar, Var1, Var2, , VarN);
Trong ú: Var1, Var2, , VarN l cỏc bin cú cựng kiu thnh phn ca FileVar.
Gp lnh ny mỏy s c cỏc giỏ tr ti v trớ ca s ang tr (nu cú) gỏn sang bin
tng ng cựng kiu. Sau ú, ca s dch chuyn sang v trớ tip theo v c giỏ tr
cho bin khỏc, c th c cho n bin VarN. READ ch cú th c giỏ tr ca tp
gỏn giỏ tr cho cỏc bin.
Vic c mt phn t ca tp cn tha món iu kin: phn t ú khụng phi l phn
t cui tp tc l EOF. Do ú, trc khi mun c tp v gỏn cho bin X, cn phi
th xem tp ú ó kt thỳc cha bng cõu lnh:
-Dòng thứ 2 chứa các số a
1
, a
2
,a
3
, a
N
các số cách nhau ít nhất một kí tự trống.
Dữ liệu ra ghi vào tệp KETQUA.OUT có cấu trúc
Tng Trn Hng
3
SKKN - Mt s dng bi tp lp trỡnh Pascal cú d liu kiu tp vn dng kin thc mng
-Một dòng trả lời kết quả của tổng
Ví dụ
DULIEU.INP KETQUA.OUT
5
4 3 6 7 8
Tong la: 28
Hng dn:
-Hiu ý ngha ca tp DULIEU.INP
Dũng 1 5 {c hiu l dũng di cú 5 s}
Dũng 2: 4 3 6 7 8 {cỏc s cỏch nhau mt du cỏch}
-Bài này giống nh tính tổng của mảng có 5 phần tử đợc nhập dữ liệu từ một tệp có
sẵn chứ không phải nhập dữ liệu khi chạy chơng trình.
-Khi viết chơng trình có 2 phần lớn:
+Phần 1: Đầu tiên ta phải đọc dữ liệu từ tệp DULIEU.INP gỏn cỏc s vo
bin .Ta gán số 5 vào biến N .Sau đó gán 5 số hàng dới vào mảng 1 chiều có 5 phần
tử.
+Phần 2: Sau khi gán các số vào mảng ta có thể xử lí giống nh bài tập mảng 1
Close(f1);close(f2);
{sau khi ghi xong dữ liệu phải đóng tệp nếu không dữ liệu sẽ không đợc ghi }
Tng Trn Hng
4
SKKN - Mt s dng bi tp lp trỡnh Pascal cú d liu kiu tp vn dng kin thc mng
Readln;
End.
Bc 3: n ctrl+f9 chy chng trình
Bc 4: m tp KETQUA.OUT xem kt qu tng.Trong tp kết qủa
KETQUA.OUT sẽ có kt qu Tong la:28
Bài 1 là dạng bài tập mà số phần tử của mảng đã đợc cho trớc trong tệp DULIEU.INP
là số đầu tiên của tệp.Nếu dạng bài không cho biết số phần tử của mảng thì ta phải có
thêm lệnh đếm số phần tử. Sau đây là bài tơng tự bài 1 nhng không cho biết số phần tử
Bi 2:: cho dãy số gồm N số tự nhiên a
1
, a
2
,a
3
, a
N .
Vit chng trỡnh in ra tng ca
N s trờn .
Dữ liệu vào cho bởi tệp DULIEU.INP có cấu trúc:
-Một dòng chứa các số a
1
, a
2
,a
3
While Not EOF(F1) Do
Begin
Readln(F1, n);
For i:=1 to n do read(f1,a[i])
End;
n:=0;
While Not EOF(F1) Do
Begin
n:=n+1;
read(f1,a[i])
End;
Bài 3: Cầu lông
Trong buổi lễ bế mạc cuộc thi đấu cầu lông .Các vận động viên đứng thành 1 hàng.Có
N vận động viên tham gia.Kết quả điểm của mỗi vận động viên thứ i là a
i
.Trong đó chỉ
có 2 vận động viên bằng điểm nhau.Hãy tìm vị trí 2 vân động viên bằng điểm nhau và
số điểm của họ .
Dữ liệu vào cho bởi tệp CAULONG.INP có cấu trúc:
-Dòng đầu tiên chứa số nguyên N
-Dòng thứ 2 chứa các số a
1
, a
2
,a
3
, a
N
các số cách nhau ít nhất một kí tự trống.
Dữ liệu ra ghi vào tệp CAULONG.OUT có cấu trúc
for i:=1 to n do read(f1,a[i]);
end;
for i:=1 to n do {bat dau duyet tung so}
for j:=i+1 to n do
if a[i]=a[j] then {nếu bằng nhau thì in ra}
Begin
writeln(f2,a[i]:3); {in ra giá trị bằng nhau}
writeln(f2,i:3,j:3); {in ra chỉ số 2 giá trị bằng nhau}
end;
close(f1);close(f2);
readln
. END.
Bài 4:cht lng
Một xng sản xuất sản phẩm trong N tháng. Ban giám đốc muốn biết khả năng sản
xuất của xởng đó.Họ muốn biết số tháng liên tục nhiều nhất mà sản phẩm liên tục
tăng và các tháng đó là tháng nào?.
Dữ liệu vào cho bởi tệp NN.INP có cấu trúc:
-Dòng đầu tiên chứa số nguyên N
-Dòng thứ 2 chứa các số a
1
, a
2
,a
3
, a
N
là số sản phẩm của tháng 1,2,3, N.
Dữ liệu ra ghi vào tệp NN.OUT có cấu trúc
- Dòng 1 là số tháng liên tục nhiều nhất mà sản phẩm liên tục tăng
end;
Max:=0; {biến max dùng để tính số lợng phần tử tăng nhiều nhất}
For i:=1 to N do
begin
s:=0;
for j:=i to n do
if a[j]<a[j+1] then s:=s+1 else break; {lệnh break là lệnh thoát vòng lặp}
{nếu các số tăng dần thì cộng thêm vào tổng s, ngợc lại nếu không tăng thì thóat
vòng lặp}
if max<s then
begin
max:=s; bd:=j-max; {bd la chi so bat dau cua day lon nhat}
end;
end;
{so luong so thang san pham tang nhieu nhat la }
writeln(f2,max+1);
{so cac thang la}
for i:= bd to bd+max do write(f2,i:3);
close(f1); close(f2);
readln
END.
B i 5: Dãy số đỉnh núi
Dãy số đỉnh núi là dãy số có số phần tử là lẻ, số chính giữa là số lớn nhất(đỉnh núi)
và phía bên trái và bên phải của số đỉnh núi các số giảm dần (xuống núi).Kiểm tra 1
dãy số có phải là dãy số đỉnh núi không?
Dữ liệu vào cho bởi tệp DINHNUI.INP có cấu trúc:
-Một dòng chứa các số a
1
, a
2
Program daydinhnui;
Uses CRT;
Var f1,f2: Text; a:array [1 20] of integer; s,n:integer;
Begin
ClrScr;
Assign(F1, DINHNUI.INP); Reset(F1);
Assign(F2, DINHNUI.OUT); Rewrite(F2);
n:=0;
While Not EOF(F1) Do
Begin
n:=n+1;
read(f1,a[i])
End;
if (n mod 2 = 0) then write(f2,'khong la day dinh nui'); { n chẵn}
else { nếu n lẻ}
begin
s:=0; t:=0;
for i:=1 to n do
begin
for i:=1 to (n div 2)+1 do
if a[i]<a[i+1] then s:=s+1 else break;
if s=((n div 2)+1) then
begin
for i:= ((n div 2)+1) to n do
if a[i]>a[i+1] then t:=t+1 else break;
end;
if t=s then write(f2,'la day dinh nui ') else
write(f2,'khong la day dinh nui');
end;
end;
8 5
14 13
Hớng dẫn:
-Đây là bài tập mảng 2 chiều tính tổng các số hàng lẻ và hàng chẵn sau đó lại tính
tổng của cột lẻ và cột chẵn
Viết chơng trình:
PROGRAM giaohuu;
uses crt;
var
i,j,k,m,n,l,s,t,tl,tc:integer;
f1,f2:text; a:array[1 100,1 100] of integer;
begin
clrscr;
assign(f1,'GIAOHUU.INP');
reset(f1);
assign(f2,'GIAOHUU.OUT');
REWRITE(F2);
while not eof(f1)do
begin
readln(f1,n,m); {n là số hàng,m là số cột}
for i:=1 to n do
for j:=1 to m do read(f1,a[j,i]);
end;
for i:=1 to n do
begin
s:=0; t:=0; j:=1; k:=2;
Tng Trn Hng
10
SKKN - Một số dạng bài tập lập trình Pascal có dữ liệu kiểu tệp vận dụng kiến thức mảng
{s lµ tæng c¸c sè hµng lÎ; t tæng c¸c sè hµng ch½n; j lµ chØ sè cét lÎ, k lµ chØ sè cét
4 5
Tống Trần Hướng
11
SKKN - Mt s dng bi tp lp trỡnh Pascal cú d liu kiu tp vn dng kin thc mng
Hớng dẫn:
-Đây là bài tập mảng 2 chiều tìm những cột nào mà giá trị phần tử hoàn toàn bằng
nhau
-In ra chỉ số cột và phần tử bằng nhau đó
Viết chơng trình:
PROGRAM bangnhau;
uses crt;
var i,j,m,n,k,t,s:integer; f1,f2:text;
a,b:array[1 100,1 100] of integer;
begin
clrscr;
assign(f1,'BANGNHAU.DAT');
RESET(f1);
assign(f2,'BANGNHAU.OUT');
rewrite(f2);
while not eof(f1) DO
begin
readln(F1,m,n);
for i:=1 to m do
for j:=1 to n do read(F1,a[i,J]);
end;
for j:=1 to n do
if i<=m then
begin
i:=1; t:=i+1;
if a[i,j]=a[t,j] then {so sánh các phần tử cột j }
-Các dòng tiếp theo ghi số hiệu của xe đợc lấy xăng theo đúng nhu cầu lấy
ví dụ:
XANG.INP XANG.OUT
20 6 5
Tng Trn Hng
12
SKKN - Mt s dng bi tp lp trỡnh Pascal cú d liu kiu tp vn dng kin thc mng
7 8 3 2 4 2 6
4
3
5
1
Hớng dẫn:
-Đây là dạng bài tập tìm tổng của nhiều phần tử nhất mà không vợt quá 20
-Ta thờng phải sắp xếp mảng đã cho theo thứ tự tăng hoặc giảm
-Ta gán mảng a vào một mảng b (để sau lấy lại chỉ số) sau đó sắp xếp tăng dần rồi
tính lần lợt tổng lợng xăng tiêu thụ.Nếu khi nào vợt quá tổng lợng xăng là 20 lít thì
dừng lại
-Minh họa thuật toán:
+Gán mảng a vào mảng b :
a
1
= b
1
=7 ; a
2
= b
2
=8 ; a
3
+ Dựa vào biến đếm ta xác định đợc 5 xe đợc lấy xăng theo đúng nhu cầu lấy
nhất
+Muốn in ra chỉ số ban đầu ta phải so sánh 5 phần tử của mảng a đã sắp xếp
tăng với mảng b để tìm chỉ số ban đầu
-Sau đó in ra số lợng xe và chỉ số của các xe đó
Viết chơng trình:
PROGRAM phanphoixang;
uses crt;
TYPE MANG=array[1 10] of integer;
var
t,n,i,k,j ,s,m:integer; a,b,c:MANG;
begin clrscr;
assign(f1, XANG.INP );
reset(f1);
assign(f2, XANG.OUT);
rewrite(f2);
while not eof(f1) do
begin
readln(F1,m,n);
for i:=1 to n do read(F1,a[i]);
end;
for i:=1 to n do b[i]:=a[i];
{do phải sắp xếp mảng a nên ta gán mảng a nào mảng b để sau nay lấy lại chỉ số mảng
a}
{sap xep mang a tang dan}
for i:=1 to n do
for j:=i to n do
Tng Trn Hng
13
i
, a
i
. Hãy giúp người đó chọn
mua một bộ quần áo sao cho giá bộ quần áo đó là lớn nhất nhưng không vượt quá số
tiền người đó mang theo?
Dữ liệu vào: File văn bản QUANAO.INP:
- Dòng đầu tiên chứa hai số nguyên dương N, M
- M dòng tiếp theo chứa các số nguyên dương .Dòng i chứa 2 số là giá quần và giá áo
của kiểu i
Kết quả: Ghi ra file văn bản QUANAO.OUT:
- Dòng đầu tiên ghi tổng số tiền bộ quần áo
- Dòng thứ 2 ghi số kiểu của bộ quần áo
QUANAO.INP QUANAO.OUT
Tống Trần Hướng
14
SKKN - Mt s dng bi tp lp trỡnh Pascal cú d liu kiu tp vn dng kin thc mng
26 4
7 15
9 15
13 16
8 13
24
2
Hớng dẫn:
-Đây là dạng bài tập mảng a 2 chiều tìm hàng có tổng lớn nhất nhng không vợt quá
26
-Ta tính tổng của từng hàng gán vào một mảng b
-Ta sắp xếp mảng b tăng dần .Xét lần lợt nếu phần tử mảng b nào vợt quá tổng lợng
tiền là 26 thì dừng lại
=21 ;
+Sắp xếp mảng b tăng dần: b
1
=21; b
2
=22; b
3
=24; b
4
=29
+So sánh các phần tử của mảng b với 26 ta có b
3
=24 là phần tử lớn nhất không
lớn hơn 26. Sau đó in ra tổng tiền lớn nhất không vợt quá 26 là 24
+Muốn in ra chỉ số của hàng ban đầu ta phải so sánh b
3
=24 với các phần tử của
mảng c để tìm chỉ số ban đầu là 2 (b
3
=24= c
2
)
Viết chơng trình:
uses crt;
type
mang=array[1 10,1 200] of integer;
var n,m,i,j,t,k,s,h:integer ;
a:mang; f1,f2:text; c,b:array[1 10] of integer;
BEGIN
b[i]:=t;
end;
for i:=1 to n do if b[i]> m then break; {nếu lớn hơn tổng số tiền m thì thoát}
for j:=1 to i do {i là giá trị ở lệnh trên sau khi thoát vòng lặp for}
if b[i-1]=c[j] then {phai tru di 1 don vi moi dung voi gia tri nho hon m}
begin
writeln(f2,c[j]:4
Write(f2,j:3);
End;
close(f1);close(f2);
readln
end.
Tng Trn Hng
16
SKKN - Mt s dng bi tp lp trỡnh Pascal cú d liu kiu tp vn dng kin thc mng
III. KếT LUậN:
Trên đây là một số kinh nghiệm của tôi khi dạy và làm bài tập Pascal dữ liệu kiểu
tệp .Tôi viết kinh nghiêm này nhằm mục đích cùng trao đổi với các thầy cô trong dạy
học lập trình Pascal thế nào cho hiệu quả đồng thời giúp cho học sinh có thể dể hiểu
hơn khi làm bài lập trình thi hoc sinh giỏi tin học . Vì kiến thức và thời gian còn hạn
chế nên còn có nhiều thiếu sót, tôi mong đón nhận sự góp ý của quý Thầy Cô. Tôi xin
chân thành cảm ơn.
Tng Trn Hng
17