Phần này trình bày cách vận dụng các câu lệnh lặp để giải quyết một số
bài toán tiêu biểu ở mức khó hơn. Thông qua các ví dụ, người học sẽ tìm
thấy những tư liệu có ích để giải các bài tập tương tự, nâng cao thêm một
bước kỹ năng lập trình.
13 trang |
Chia sẻ: maiphuongdc | Lượt xem: 10412 | Lượt tải: 2
Bạn đang xem nội dung tài liệu Pascal - Các ví dụ nâng cao về câu lệnh lặp, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
CÁC VÍ DỤ NÂNG CAO VỀ CÂU LỆNH LẶP
Phần này trình bày cách vận dụng các câu lệnh lặp để giải quyết một số
bài toán tiêu biểu ở mức khó hơn. Thông qua các ví dụ, người học sẽ tìm
thấy những tư liệu có ích để giải các bài tập tương tự, nâng cao thêm một
bước kỹ năng lập trình.
Ví dụ 11.1: Nhập x và n, tính gần đúng Sinx theo công thức:
Ta viết :
S= U0 - U1 + U2 - U3 +U4 - ... +(-1)N UN , trong đó :
U0 = x
.v.v.
Như vậy, Uk sai khác Uk-1 một thừa số C có thể tính trực tiếp được theo x
và theo k :
Thành ra, nếu lưu được số hạng U ở bước trước thì sẽ tính được số hạng U
ở bước sau bằng lệnh : U:=U*C; , và vì sang bước sau thì gía trị U sẽ thay
đổi nên tại mỗi bước ta phải cộng hoặc trừ ngay U vào tổng S.
Việc cộng hay trừ U vào tổng S được giải quyết nhờ một biến dau gọi là
biến chứa dấu của U, biến này chỉ nhận gía trị là +1 hay -1 ứng với phép
cộng hay trừ U vào tổng S.
Ðầu tiên ta gán:
dau:= -1;
Tại mỗi bước lặp ta cộng U đã nhân với dau vào S, rồi đảo dấu đi để
chuẩn bị cho bước tiếp theo bằng các lệnh:
S:= S+ dau * U;
dau:= -dau ;
Thành ra nếu bước trước dau=-1 thì ở bước sau dau=+1 và ngược lại. Kết
qủa là lệnh S:= S+ dau * U; sẽ cộng hay trừ U vào S theo luật đan dấu.
Câu lệnh lặp được dùng ở đây là lệnh FOR vì số lần lặp N được nhập từ
bàn phím tức là đã biết trước. Chương trình cụ thể như sau:
PROGRAM VIDU11_1;
{ Tính gần đúng Sinx }
Var
N, k, dau : Integer;
x, U, S, C : Real;
Begin
Write(‘Nhập số dương N : ‘); Readln(N);
Write(‘Nhập số thực x : ‘); Readln(x);
U:=x;
S:=x ; { Gán gía trị ban đầu U0 cho S ngay}
dau:= -1;
For k:=1 to N do
begin
C:= x*x/ ( 2*k*(2*k+1) );
U:= U*C;
S:=S+ dau*U;
dau:= - dau;
end;
Writeln(‘ Giá trị Sin = ‘, S:8:4);
Readln;
End.
Chạy
Chép tập tin nguồn
Khi chạy chương trình, nếu nhập N=6 và x=1.5708 (= /2) thì cho kết
qủa Sinx= 1.0000 ; Nếu nhập N=6 và x=3.1416 (= ) thì cho kết qủa Sinx =
0.0000.
Ví dụ 11.2: Tính gần đúng số e với sai số cho trước.
Cho công thức :
( vế phải là một tổng vô hạn )
Hãy tính gần đúng e2 bằng cách lấy tổng ( hữu hạn ) các số hạng ở đầu
chuỗi cho đến khi gặp số hạng đầu tiên có gía trị tuyệt đối nhỏ hơn một số
epsilon (EPS) dương khá bé cho trước, tức là :
với n là số sao cho:
.
Ta viết :
S = Uo +U1 +...+Un , trong đó :
Uo=1
.v.v.
Tương tự ví dụ 11.1, ta dùng biến U để lưu số hạng tại mỗi bước lặp k=0,
1, 2, ... Tại mỗi bước, ta kiểm tra nếu U EPS thì cộng U vào tổng S,
rồi tính U cho bước tiếp theo bằng cách nhân U với thừa số 2/k. Qúa trình
kết thúc khi gặp số hạng U đầu tiên có U < EPS. Vì số vòng lặp là
không biết trước nên câu lệnh lặp được dùng là WHILE. Chương trình được
viết như sau :
PROGRAM VIDU11_2;
{ Tinh e2 theo sai số EPS dương khá bé cho trước}
Var
k : Integer;
S, U, EPS : Real;
Begin
Repeat
Write(‘Nhap sai so > 0 : ‘);
Readln(EPS);
Until EPS >0;
k :=0;
S :=0;
U :=1;
While ABS(U) >= EPS DO
begin
S:=S +U;
k:=k+1;
U:=U* 2/ k;
end;
Writeln(‘ S= ‘ , S:8:4 , ‘ tính đến số hạng k= ‘, k);
Readln;
End.
Chạy
Chép tập tin nguồn
Khi chạy chương trình, nếu nhập EPS=0.001 thì cho kết qủa S=7.3887 ,
tính đến số hạng k=10.
Ví dụ 11.3:
Nhập số nguyên dương N, in các chữ số của N theo thứ tự đảo ngược. Ví
dụ N= 15742 in ra 24751. Cách làm như sau:
Tách và in hàng đơn vị của N ra bằng hai lệnh:
k:= N mod 10; { được k=2 }
Write(k: 3);
Bỏ đi hàng đơn vị, giữ lại các chữ số từ hàng chục trở lên:
N:= N div 10; { được N=1574 }
Lặp lại qúa trình trên cho đến khi N=0.
Số lần lặp là không biết trước mà tùy thuộc vào việc nhập số N có ít hay
có nhiều chữ số, nên ta phải dùng lệnh Repeat hay While.
PROGRAM VIDU11_3;
{ In đảo ngược các chữ số của N }
Var
N, k: LongInt ;
Begin
Repeat
Write(‘ Nhập N : ‘);
Readln(N);
Until (N>0);
Writeln( N, ‘ được in đảo ngược thành :’);
Repeat
k:= N mod 10;
Write(k: 3);
N:=N div 10;
Until N=0;
Readln;
End.
Chạy
Chép tập tin nguồn
Ví dụ 11.4: Kiểm tra số tự nhiên N có phải số nguyên tố không.
Số N 1 là số nguyên tố nếu nó chỉ chia hết cho 1 và chính nó. Ví dụ các
số 2, 3, 5, 7, 11, 13, 17, 19, 21, 23 đều là số nguyên tố.
Xuất phát từ địng nghĩa, ta kiểm tra nếu N không chia hết cho tất cả các
số từ 2, 3, 4, ..., đến N-1 thì N là nguyên tố, ngược lại, chỉ cần N chia hết cho
một số k nào đó trong tập { 2, 3, 4, ..., N-1} thì N không phải số nguyên tố.
PROGRAM VIDU11_4;
{ Kiểm tra số N có phải số nguyên tố không }
Var
N, k: integer;
Kiemtra: Boolean ;
Begin
Repeat
Write(‘ Nhập N : ‘);
Readln(N);
Until (N>0);
If N =1 then Kiemtra:= False
else { xét N > 1}
begin
Kiemtra:= True;
k:=1;
Repeat
k:= k+1;
Until N mod k=0 ;
If k<N then Kiemtra:= False;
end;
If Kiemtra=True then Writeln(N, ‘ là số nguyên tố ‘)
else
Writeln(N, ‘ không phải số nguyên tố ‘);
Readln;
End.
Chạy
Chép tập tin nguồn
Chương trình có một đoạn cần giải thích rõ thêm:
Repeat
k:= k+1;
Until N mod k=0 ;
If k<N then Kiemtra:= False;
Vòng lặp trên kết thúc khi gặp số k đầu tiên (nhỏ nhất) thỏa điều kiện N
mod k=0. Lúc đó, nếu k<N thì có nghĩa N chia hết cho một số k khác N nên
N không phải số nguyên tố. Nếu k=N thì chứng tỏ N chỉ chia hết cho N và
không chia hết cho các số 2, 3, ..., N-1 nên N là số nguyên tố.
Nhận xét: Vì số chẵn (trừ số 2) không phải số nguyên tố nên chương trình
có thể cải tiến chỉ kiểm tra các số lẻ thôi.
Các file đính kèm theo tài liệu này:
- cac_vi_du_nang_cao_ve_cau_lenh_lap_4976.pdf