Thuật toán xử lý căn số, phân số trong Pascal
Trang 1Xử lý căn số, phân số trong Pascal
Trương Thị Thu Hường
Xử lý cănsố, phân số trong Pascal sẽ là dễ dàng nếu chúng ta sử dụng các hàmcó sẵn như sqrt(a) hay thực hiện1 phép chia đơn thuần Nhưng cũng sẽ thật phức tạp nếu kết quả chora lại là số thực hay kết quả gần đúng trong khi chúng ta cần nhữngcon số chính xác
Ví dụ: khi ta giải hệ phương trình
Kết quả máy cho ra:
Hay việc nhập hệ số khi giải hệ phương trình cũng rất khó khăn vì là một số thực Vì vậy, tìm cách xử lý để không có những con số thực như vậy là việc mà nhiềubạn đã nghĩ tới Với mỗi bạn khác nhau, chúng ta có thể có những cáchsuy nghĩ và hướng giải quyết khác nhau Sau đây, tôi xin trình bày một cách mà tôi đã sử dụng đểxoá
bỏ điều này khi làm bài trong Pascal
Chúng ta hãy dịch một kiểu mới dựa vào những kiểu dữ liệu chuẩn có sẵncủa Pascal Type
so=record
tu: array[1 2] of integer;
mau: array[1 2] of integer;
phu:string[60];
end;
Một số luôn tồn tại dưới dạng phân thức trong đó, tử (mẫu) gồm 2 thành phần tu[1] (mau[1]) chỉ bậc của căn (nếu tu[1]=1) tử là một số nguyên) tu[2] (mau[2]) là giá trị của
số dưới dấu căn Ngoài ra, 1 số còn có thêm trường phụ kiểu xâu để lưu dữ liệu sốtrong trường hợp đó là 1 tổng đạisố các căn thức
a.phu=′(2,2,1,2) - (3,2,1,3)′
Tuy nhiên, việc nhập hay ghi ra 1 số cũng phức tạp hơn Chúng ta hãy quy ước 1 số chỉ gồm 1 trong 4 dạng sau:
Trang 2Điểm khácnhau giữa chúng chính là số lượng kí tự ′,′ và ′+′, ′-′ Dựavào điểm này, chúng ta
có thể viết được thủ tục nhập dưới đây:
ProcedureNhap(var a: so);
var d,i: byte; s: string[60];so, code: integer;
hs: array[1 4] of integer;
Begin
Fillchar(hs, sizeof(hs),0) ;
a.tu[1]:=1;
a.mau[1]:=1;
a.mau[2]:=1;
repeat
write(′Vao so: ′); readln(s);
until ((Pos(′(′,s)=0)and (Pos(′)′,s )=0)) or ((Pos(′(′,s)<>0) and (Pos(′)′,s )<>0));
If (Pos(′+′, s)<>0) or (Pos(′-′,s)<>0) then
begin
a.phu:=s;
exit;
end;
ifPos(′,′,s) =0 then s:=′(′+S+ ′)′;
d:=0; insert(′,′,S, length(S));
While(S<> ′()′) do
begin
inc(d); i:=pos(′,′,S);
Val(Copy(S,2,i-2),so,code);
hs[d]:=so; Delete(S,1,i); S:= ′(′+S ;
end;
Ifd=1 then a.tu[2]:=hs[1];
Ifd=2 then begin a.tu[2]:=hs[1]; a.mau[2]:=hs[2]; end;
Ifd=4 then
begin
a.tu[1]:=hs[1]; a.tu[2]:=hs[2];
a.mau[1]:=hs[3]; a.mau[4]:=hs[4];
end;
end;
Nhưng cũngcần lưu ý, khi nhập vào một số, chúng ta cần nhập đúng dạng (1trong 4 dạng trên) nếu không sẽ rất dễ bị sai kết quả hay không đảm bảo tính dừng
Để ghi ra1 số, chúng ta cũng in ra bằng 1 trong 4 dạng trên, riêng với phân sốđược biểu diễn là a/b Dưới đây là thủ tục ghi 1 số ra màn hình:
ProcedureGhi(a: so); (* Đây là một số đã được trục căn thức, không còn cănthức dưới mẫu
Trang 3a.mau[1]=1 *)
var s:string[60]; c1: string[10];
Begin
s: =′′;
Ifa.phu<>′′ then
begin
s:= ′(′ + a.phư ′)′;
if a.mau[2] <>1 then
begin
str(a.mau[2], c1);
s: =s+′/′ + c1;
end;
end
else
begin
str(a.tu[2],c1);
s:=s+c1;
if a.tu[1]<>1 then
begin
str(a.tu[1],c1); S:= ′(′+c1+ ′,′ + S+′,1,′ ;
str(a.mau[2],c1); S:=S+ c1+′)′ ;
end
else
begin
str(a.mau[2],c1);
if c1<>′1′ then
begin
c1:= ′/′ +c1;
S:=S+c1;
end;
end;
end;
end;
Ngoài việcnhập và ghi ra 1 số, các phép tính như +, - , *, / và các phép toánphụ khác như trục căn thức, rút gọn, các bạn đều có thể tự viết được Ngoài cách làm trên, các bạn cũng có thể có những cách khác nữa Hy vọng rằng, với 1 kiểu số mới này,các bạn sẽ dễ dàng hơn khi làm các bài toán như giải hệ phương trình,giải phương trình, viết phương trình đường thẳng qua hai điểm bấtkỳ Chúng ta sẽ không còn gặp số gần đúng, để những con số đượcmáy tính hoá, đưa ra sẽ luôn là những con số chính xác