PDA

View Full Version : Một số kĩ thuật cơ bản của Pascal



chungkid1
24-12-2007, 22:45
Mình lập ra topic này để chia sẻ một số kinh nghiệm của cá nhân mình về một số kĩ thuật cơ bản sẽ được sử dụng khá nhiều,bạn nào biết hơn hãy post vào đây để chia sẻ với những ai chưa biết.Mình sẽ cố gắng cập nhật thêm.
Chúng ta hãy bắt đầu với một số kĩ thuật đơn giản

+Muốn dừng màn hinh lại để có thể xem kết quả sau khi chương trình đã chạy xong,hãy thêm vào trước cái END cuối cùng của chương trình một câu lệnh Readln;
+Cách in ra ma trận a với m dòng,n cột dưới dạng bảng


for i:=1 to m do begin
for j:=1 to n do
write(a[i],' ');
writeln;
end;

+Hoán đổi vị trí của hai số a,b,sử dụng một biến tg làm trung gian


Procedure Swap(Var a,b:integer);
Var tg:integer;
Begin
tg:=a;
a:=b;
b:=tg;
End;

Thôi,tạm dừng ở đây.Sẽ cập nhật tiếp vào lúc khác

bete
25-12-2007, 02:00
Tui nghĩ sau này bạn chungkid có thể sẽ thay đổi ý kiến về:

+Hãy thay câu lệnh inc(i) của bạn trong chương trình bằng câu lệnh i:=i+1.Vì sao à?Bởi vì câu lệnh sau tuy dài nhưng nó chạy nhanh hơn câu lệnh trước,ko tin hãy chạy mỗi cái khoảng 1 tỷ lần,bạn sẽ thấy nó khác như thế nào
(1 trình biên dịch tốt có đủ thông minh để dịch "inc(i)" giống y như "i:=i+1"
Cho dù "i:=i+1" có thiệt sự chạy nhanh hơn "inc(i)" đi nữa: xài đúng cấu trúc dữ liệu và thuật toán sẽ làm chương trình chạy nhanh hơn rất nhiều so với việc đổi "inc(i)" thành "i:=i+1")

+Thay vì viết (a) and (b),bạn hãy viết thế này
if a then
if b then
như thế nhiều khi có thể loại được một số bước xét ko cần thiết,làm chương trình có thể chạy nhanh hơn một chút.Hơn nữa có thể tránh một số lỗi vớ vẩn vì TP7 nhiều khi bị điên,viết (a) and (b) nó xét a đã sai rồi,nó xét b đúng nó vẫn chạy tiếp
(nếu bạn chắc chắn TP7 bị lỗi như vậy thì không nên xài nó làm gì !!!
Nhưng tui không biết bạn có lộn chỗ này hay không ? Tui nghĩ có thể là nó xét a sai rồi nó vẫn xét b tiếp; nhưng cuối cùng thì nó vẫn nhảy qua phần "else")

Nhưng cũng cám ơn bạn đã có ý tốt muốn chia sẻ kinh nghiệm

(hiểu biết nông cạn; có gì sai sót mong được góp ý; xin cám ơn)

-thân

amida
25-12-2007, 08:55
Tôi có thắc mắc 1 tí.


+Hãy thay câu lệnh inc(i) của bạn trong chương trình bằng câu lệnh i:=i+1.Vì sao à?Bởi vì câu lệnh sau tuy dài nhưng nó chạy nhanh hơn câu lệnh trước,ko tin hãy chạy mỗi cái khoảng 1 tỷ lần,bạn sẽ thấy nó khác như thế nào

Hàm inc() là hàm viết sẵn (structured function) cho pascal để thao tác trực tiếp với mã máy, vì vậy tôi không nghĩ rằng inc(i) lại chậm hơn i := i + 1; Trong trường hợp i := i + 1; compiler cũng phải dịch rồi xác định cái thằng "+" đó là dấu cộng rồi mới thực hiện phép tính.


+Cách in ra ma trận a với m dòng,n cột dưới dạng bảng
for i:=1 to m do begin
for j:=1 to n do
write(a[i],' ');
writeln;
end;
Code standard cũng là kỹ thuật lập trình thì phải. Theo tôi với mấy ngôn ngữ dùng chữ thì chúng ta không nên để begin cùng hàng với câu lệnh trước nó để tránh tình trạng rối mắt, bỏ sót cặp begin-end .v.v

Một chút ý kiến, không biết đúng hay sai. Cám ơn vì chia sẻ kinh nghiệm.

mr_invincible
25-12-2007, 17:48
+Thay vì viết (a) and (b),bạn hãy viết thế này
if a then
if b then
như thế nhiều khi có thể loại được một số bước xét ko cần thiết,làm chương trình có thể chạy nhanh hơn một chút.Hơn nữa có thể tránh một số lỗi vớ vẩn vì TP7 nhiều khi bị điên,viết (a) and (b) nó xét a đã sai rồi,nó xét b đúng nó vẫn chạy tiếp

Tôi không nghĩ điều bạn nói ở trên là đúng. Tôi đã sử dụng TP7 2 năm nay và chưa bao giờ thấy có cái lỗi mà bạn nêu trên. Hơn nữa, trong TP7, việc bạn viết tách 2 câu lệnh đó ra chẳng ảnh hưởng gì cả, không biết bạn đã thử chưa. Đối với phép and, nếu viết (a) and (b) thì khi a sai, TP7 sẽ không xét tiếp b nữa, nếu không tin bạn có thể thử cho a và b là các function rồi dùng F7 (trace into) bạn sẽ thấy chương trình không hề quan tâm tiếp đến b

mr_invincible
25-12-2007, 17:56
+Hãy thay câu lệnh inc(i) của bạn trong chương trình bằng câu lệnh i:=i+1.Vì sao à?Bởi vì câu lệnh sau tuy dài nhưng nó chạy nhanh hơn câu lệnh trước,ko tin hãy chạy mỗi cái khoảng 1 tỷ lần,bạn sẽ thấy nó khác như thế nào


Chính tay tôi đã thử sự khác nhau của 2 lệnh trên:
- Nếu đặt chỉ thị dịch là $R+ (kiểm tra lỗi tràn số) thì với lệnh i:=i+1 thì TP7 phải kiểm tra xem lệnh trên có gây ra tràn số không, do đó lệnh i:=i+1 chậm hơn rất nhiều so với inc(i) (khoảng gần 2 lần)
- Nếu đặt chỉ thị dịch là $R- (không kiểm tra lỗi tràn số) thì do không phải kiểm tra xem có tràn số không nên lệnh i:=i+1 có nhanh hơn một chút, nhưng vẫn chậm hơn nhiều so với inc(i)

Lý do duy nhất mà tôi nghĩ nên dùng i:=i+1 hay i:=i+n mà không thay bằng inc(i,n) là do TP7 không kiểm tra tính tràn số của lệnh này, nên trong các chương trình lớn, khó kiểm tra được tính đúng đắn của lệnh này (không thể biết lệnh này có gây tràn số không)

chungkid1
25-12-2007, 20:24
Code standard cũng là kỹ thuật lập trình thì phải. Theo tôi với mấy ngôn ngữ dùng chữ thì chúng ta không nên để begin cùng hàng với câu lệnh trước nó để tránh tình trạng rối mắt, bỏ sót cặp begin-end .v.v
sorry,tôi dã để mấy dấu space rồi đấy chứ,ko hiểu vì sao nó lại bị mất,sẽ sửa ngay.Cảm ơn vì đẫ nhắc nhở.

Đa tạ vì ý kiến đóng góp của mọi người.Có lẽ mình đã sai ở hai ý cuối.Mình
sẽ del hai ý đó đi.Xin lỗi về sự nhầm lẫn này.

chungkid1
25-12-2007, 20:55
Tiếp nhé
+Hàm kiểm tra số nguyên tố,trả về true nếu số n là số nguyên tố


Function nt(n:integer):boolean;
Var
i:integer;
Begin
if n<=1 then begin
nt:=false;
Exit;
end;
for i:=2 to (n div 2) do
if (n mod i)=0 then begin
nt:=false;
Exit;
end;
nt:=true;
End;

+Hàm tính giai thừa(loại cơ bản,áp dụng cho số nguyên dương n<=15)


Function gt(n:byte):Longint;
Var
s:Longint;
i:byte;
Begin
s:=1
For i:=2 to n do
s:=s*i;
gt:=s;
End;

+Sắp xếp mảng a với n phần tử theo thứ tự tăng dần,sử dụng thuật toán Bubble Sort


Procedure BubbleSort(Var a:mang,n:integer);{Mang là kiểu array khai báo
bằng từ khóa Type}
Var i,j:integer;
Begin
for j:=1 to n-1 do
for i:=n downto j+1 do
if a[i]<a[i-1] then
Swap(a[i],a[i-1];{Thủ tục Swap ở trên})
End;

Phương pháp này chạy chậm với những bộ dữ liệu lớn,vì vậy khi cần phương pháp sắp xếp tốt hơn,bạn nên dùng phương pháp Quick sort.Chương trình của nó có sẵn trong thư mục Example của Pascal,là file QSort.pas.Tuy nhiên bạn nên nhớ lấy để dùng,ko nên quá ỷ lại vào chương trình có sẵn,rủi bị ai xóa mất thì chỉ có khóc thôi

mr_invincible
25-12-2007, 21:30
Hàm kiểm tra nguyên tố có lẽ nên để i chạy từ 2 đến round(sqrt(n)) thì chương trình sẽ chạy nhanh hơn (nhất là đối với các số lớn khoảng một hai triệu)

bete
26-12-2007, 02:15
Hàm kiểm tra nguyên tố có lẽ nên để i chạy từ 2 đến round(sqrt(n)) thì chương trình sẽ chạy nhanh hơn (nhất là đối với các số lớn khoảng một hai triệu)

=> nếu muốn cho nhanh hơn 1 chút nữa:
- nếu n là số chẵn thì ....
- cho i là số lẻ chạy từ 3 đến round(sqrt(n))

(nhưng có vẻ mấy cái về sau không còn là "kỹ thuật cơ bản của Pascal nữa" (không là kỹ thuật; mà cũng không là chỉ đúng cho riêng Pascal))

(hiểu biết nông cạn; có gì sai sót mong được góp ý; xin cám ơn)

-thân

real_time
26-12-2007, 09:24
Có lẽ nên đổi tên là thư viện, những đoạn chương trình mẫu viết bằng ngôn ngữ Pascal thì đúng hơn. Tui stick nó nhé.

mr_invincible
27-12-2007, 23:44
Nếu muốn tăng tốc phần kiểm tra tính nguyên tố của một số thì có thể dùng nhận xét:
- Xét dãy gồm các số -1, 5, 7, 11, 13, 17, 19, 23, 25, 29, 31...
Số thứ 2n = số thứ 2n-1+6 và số thứ 2n+1= số thứ 2n+2
- Người ta đã chứng minh được dãy trên chứa tất cả các số nguyên tố (trừ 2 và 3) và một số hợp số khác (không nhiều lắm). Do đó khi xét tính nguyên tố của một số ta chỉ cần kiểm tra xem số đó có chia hết cho 3 và mọi số trong dãy (nhỏ hơn số đó) không

Còn nếu muốn liệt kê các số nguyên tố thì có thể có hướng dùng các cách sau
- Sử dụng Sàng Eurathosten (chẳng hiểu tôi viết tên có đúng không nhỉ?) bằng cách dùng một mảng đánh dấu, nhưng do dung lượng mảng cho phép trong Turbo Pascal khá ít nên bạn nào đã biết dữ liệu động có thể sử dụng cấu trúc này để tăng số phần tử
- Có thể lưu lại các số nguyên tố đã tìm được vào một mảng rồi khi cần tìm số mới thì thử chia cho các số nguyên tố đã tìm được
Có gì sai sót mong các bạn góp ý

mr_invincible
27-12-2007, 23:55
Tôi xin góp thêm cho các bạn một thuật toán sắp xếp cũng khá đơn giản (hình như tên là Straight Selection)
- Giả sử có mảng số thực tên là a, số phần tử là n:
Procedure SapXep;
Var
i,j:integer;
tg:real;
Begin
For i:=1 to n-1 do
For j:=i+1 to n do
If a[i]>a[j] then
begin tg:=a[i]; a[i]:=a[j]; a[j]:=tg; end; {Đổi chỗ 2 số}
End;
Độ phức tạp của thuật toán này và Bubble Sort là tương đương nhau
Ý tưởng của thuật toán Sắp xếp nhanh (Quick Sort)
- Chia dãy thành 2 nửa, lấy điểm giữa làm mốc, sắp xếp lại các số trong dãy sao cho các số nhỏ hơn mốc nằm về một phía, các số lớn hơn mốc nằm về phía còn lại, lặp lại bước này đến khi toàn bộ dãy đã được sắp xếp tăng
Còn chương trình mẫu thì bạn chungkid đã nói rồi
- Độ phức tạp O(n log n)
- Ngoài ra, còn có rất nhiều thuật toán sắp xếp khác (insertion sort, merge sort, heap sort...). Mỗi thuật toán sắp xếp đều có ưu điểm và nhược điểm riêng của nó. Bạn nào quan tâm có thể tham khảo trong các tài liệu về pascal (tôi cũng chẳng biết sách nào, các bạn chịu khó tự tìm mua nhé)

Có gì sai sót mong các bạn góp ý

cashier
28-12-2007, 21:23
Lâu lắm mới nghía vô diễn đàn, đọc bài này cũng thấy hay hay, khá là có ích đối với những người mới lập trình nhưng mà ngay cái #1 đã có vấn đề rồi nè mà không ai phát hiện ra :)
Tức là cái viết ra ma trận theo hàng và cột đó, của bạn chung ghi thế thì chưa nó còn báo lỗi cú pháp trước khi ghi ra sai ấy chứ


for i:=1 to m do begin
for j:=1 to n do
write(a[i],' ');
writeln;
end;

=> lỗi trầm trọng :(
phải sửa thành là :


for i:=1 to m do
begin
for j:=1 to n do
write(a[i,j],' ');
writeln;
end;
<-- thấy sai chưa :lick:


Tiện thể ghi luôn cách nhập ma trận m hàng n cột từ bàn phím ( hồi mới học cũng mãi mới hiểu lúc nào thì phẩy trên mà lúc nào thì phẩy dưới :) )



write('nhap m: '); readln(m);
write('nhap n: '); readln(n);
for i:=1 to m do
for j:=1 to n do
begin
write('A[',i,',',j,']= '); readln(a[i,j]);
end;




(@chungkid : cơ mà đây là tranh thủ lúc đợi máy diệt virut đó, không bình thường thì "Nu, pogodi!" :D , gõ mấy dòng mà sắp đông tay lại rùi đây nè :crying: )

cashier
28-12-2007, 21:43
Tiếp nào, đã có sắp xếp thì phải có tìm kiếm chứ nhỉ, để tui bắt đầu với bài toán tìm kiếm đơn giản và cơ bản nhất nhá : Tìm xem số x có mặt trong mảng a gồm n phần tử hay không :


function kt(x:integer):boolean;
var i:integer;
begin
kt:=true;
for i:=1 to n do
if a[i]=x then exit;
kt:=false;
end;


ngoài ra, đối với mảng đã sắp xếp, người ta sẽ tìm kiếm nhị phân ( BSearch thì phải - cũng không bít nhớ có đúng không nữa :( )
ý tưởng cơ bản của thuật toán chia đôi không gian tìm kiếm, xét xem x thuộc nửa nào rồi tiếp tục chia đôi không gian đó ra cho đến khi gặp phần tử = x hoặc không tìm thấy phần tử nào = x trong không gian tìm kiếm

Và thêm nữa là tìm kiếm theo chiều sâu và tìm kiếm theo chiều rộng .
Mấy vấn đề này, thực ra em cũng chỉ biết sơ sơ, không am hiểu lắm nên mong được mọi người chỉ giáo ! :)


(@chungkid: tay hoá đá rồi nà, thế này thì mai chắc phải ngồi cạnh cái lò có cái chảo trong có một số thứ ấm ấm rồi :drool: ; T_T : 75% - 372 viruts :no:)

chungkid1
28-12-2007, 23:27
Sorry bà con,mấy hôm nay bận ko post được,với lại kiến thức có hạn,nghĩ mãi chả biết post gì,hôm nay chỉ post được hai cách tính x^y(x lũy thừa y)
Cách 1:Viết hàm
Cách này dễ nhất,ai cũng có thể nghĩ ra,nhưng tôi cứ post vào đây cho bài nó
dài(^.^)


Function GT(x,y:integer):Longint;
Var
i:integer;
s:longint;
Begin
s:=1;
for i:=1 to y do
s:=s*x;
gt:=s;
End;


rồi,rất dễ phải ko
Cách hai:
x^y=exp(y*ln(x))
biểu thức exp(y*ln(x)) sẽ trả về một giá trị real,nếu bạn cần giá trị nguyên có thể dung hàm trunc()
CHÚ Ý:Tôi đang bí chả biết post gì,vì vậy kêu gọi anh em có biết gì hãy post vào đây để cho các bạn mới học có thể tham khảo,ko cần lập topic trong forum

Master_Baby
30-12-2007, 16:55
- Gửi ChungKid:
Bạn ui, longint rất dễ bị tràn, đặc biệt là trong phép tính lũy thừa hay giai thừa. Có thể khắc phục bằng cách xài real hoặc extended, tuy nhiên hai kiểu dữ liệu này đều thuộc loại gần đúng nên nếu xài với số lớn thì không nên tin tưởng. (tui cũng không nhớ là C hay Pascal, trước tui có thử round(0.7 + 0.3) = 1 nhưng trunc(0.7 + 0.3) = 0, lý do là 0.7 + 0.3 không bằng 1.0 mà thực ra là bằng 0.(9))
Cách tốt nhất là dùng phương pháp nhân số lớn, có thể lưu trong mảng hoặc danh sách liên kết. Thường lưu trong mảng là đủ, nếu thích có thể xài danh sách liên kết cho chủ động cũng được ^^.
Còn điểm này nữa, với r kiểu real và i kiểu integer thì phép gán r:= i * 2000000000 gây lỗi tràn số, mặc dù giới hạn của real rất lớn (vì i kiểu integer, 2 tỷ kiểu longint, kết quả phép nhân trả về kiểu longint, với i > 2 kết quả vượt quá giới hạn của longint)
- Gửi Cashier:
Binary Search chỉ áp dụng được với mảng đã sắp xếp thui
Ngoài ra còn có phương pháp cây tìm kiếm nhị phân và cây tìm kiếm cơ số, nhưng hai cách này thường chẳng ai áp dụng vì khá khó nhớ và không cần thiết (tìm kiếm trong khoảng vài chục hay vài trăm phần tử mà cài 2 cách này thì quả là... phí phạm ^^)
- Gửi... mọi người :):
Về quicksort:


const
MAX = 10000;
var
x: integer;
a: array[1..MAX] of integer;
procedure qSort(l: integer; r: integer);
var
i: integer;
j: integer;
tg: integer;
begin
x:= a[l + random(r - l + 1)];
i:= l;
j:= r;
repeat
while (a[i] < x) do inc(i);
while (a[j] > x) do dec(j);
if (i <= j) then
begin
tg:= a[i];
a[i]:= a[j];
a[j]:= tg;
end;
until i >= j;
if (i < r) then qSort(i, r);
if (j > l) then qSort(l, j);
end;

Ngoài quick sort còn có merge sort, chạy khá hiệu quả. Tư tưởng của merge sort như vầy:
- Với 2 dãy đã sắp xếp tăng dần, việc "trộn" 2 dãy để dãy kết quả cũng tăng dần là khá dễ dàng: so sánh phần tử đầu tiên trong 2 dãy, phần tử nào nhỏ hơn thì đẩy vào dãy kết quả, "dồn toa" lên. Cứ như vậy cho đến lúc hết dãy.
- Có thể áp dụng phương pháp trên với n dãy tăng dần: tương tự như quick sort, phân đoạn ra sắp xếp, rồi trộn 2 đoạn cạnh nhau lại, cuối cùng có một dãy tăng dần.

Bàn một chút về sorting nhá :). Mặc dù có khá nhiều phương pháp sắp xếp, nhưng bubble sort vẫn được nhiều người sử dụng nhất vì rất rất dễ nhớ, dễ hiểu cho mọi người, kể cả với người mới học. Và giới hạn yêu cầu thường chỉ vài chục hay nhiều lắm là vài trăm trong các bài toán thông thường, nên với bubble sort O(n^2) là chấp nhận được.

Lâu không code nên có thể có sai sót, nhờ mọi người chỉ giúp -'______'-.


P/s: Cashier ui, bạn học lớp 11 ah, giờ mình mới để ý cái chữ ký trắng của bạn đấy. "Đồng cảnh ngộ" nè ^^

cashier
30-12-2007, 20:05
hum nọ vừa làm một bài toán là cho số n m tìm căn bậc n của a thế nên phải làm một hàm tính m mũ n ( với số lớn - đương nhiên :) )
post lên đây mong các bạn góp ý :


function cong_2_xau(st1,st2:string):string;
var i,so1,so2,nho:byte;
sai:integer;
kq,tam:string;
begin
nho:=0; kq:='';
while length(st2)<length(st1) do st2:='0'+st2;
while length(st2)>length(st1) do st1:='0'+st1;
for i:= length(st2) downto 1 do
begin
val(st1[i],so1,sai);
val(st2[i],so2,sai);
str((so1+so2+nho) mod 10,tam);
kq:=tam+kq;
nho:=(so1+so2+nho) div 10;
end;
if nho<>0 then
begin
str(nho,tam);
kq:=tam+kq;
end;
cong_2_xau:=kq;
end;
function nhan_xau_so(st1,st2:string):string;
var i,so1,so2,nho:byte;
sai:integer;
kq,tam:string;
begin
nho:=0; val(st2[1],so2,sai);
kq:='';
for i:= length(st1) downto 1 do
begin
val(st1[i],so1,sai);
str((so1*so2+nho) mod 10,tam);
kq:=tam+kq;
nho:=(so1*so2+nho) div 10;
end;
if nho<>0 then
begin
str(nho,tam);
kq:=tam+kq;
end;
nhan_xau_so:=kq;
end;
function nhan_so_so (st1,st2:string):string;
var i:byte;
kq:string;
begin
kq:='';
for i:=1 to length(st2) do
begin
kq:=cong_2_xau(kq+'0',nhan_xau_so(st1,st2[i]));
end;
nhan_so_so:=kq;
end;
function tinh(m:longint; n:byte):string;
var st,kq:string;
i:byte;
begin
str(m,st);
kq:=st;
for i:=1 to n-1 do
kq:=nhan_so_so(kq,st);
tinh:=kq;
end;

ý tưởng cơ bản của mình là nhân số m n lần, với mỗi lần nhân mình thực hiện phép nhân 2 số lớn , mà phép nhân 2 số lớn thực hiện như theo thực hiện tay là nhân với từng số một rồi cộng vào
Mình đã chạy và ra kết quả đúng nhưng gọi là số lớn mà cái của mình thì chỉ chạy với số mà ra kết quả có nhiều nhất 255 kí tự ( vì dùng xâu mà :) ) tức là chỉ cỡ 10^255 hoặc là 2147483647 ^ 30
Còn chuyển sang DLLK thì xem chừng phải thay đổi lại thuật toán :emlaugh:
Mong các bạn góp ý thêm

@Master_Baby : Bạn tinh thật đấy, không ngờ vẫn có người chú ý và đọc được ( chắc tại "đồng cảnh ngộ " :D ), mà sao bạn biết mình học lớp 11 zậy, hay quá ( chắc cũng lại .. :) ) Dù sao cũng rất vui được bít thêm 1 người " đồng cảnh ngộ "

mr_invincible
31-12-2007, 11:21
ý tưởng cơ bản của mình là nhân số m n lần, với mỗi lần nhân mình thực hiện phép nhân 2 số lớn , mà phép nhân 2 số lớn thực hiện như theo thực hiện tay là nhân với từng số một rồi cộng vào
Còn chuyển sang DLLK thì xem chừng phải thay đổi lại thuật toán :emlaugh:
Mong các bạn góp ý thêm


Dùng Danh sách liên kết thì cũng vậy thôi, cũng nhân theo từng chữ số rồi cộng vào là được mà

bete
31-12-2007, 14:16
Thân gửi bạn cashier,

Tui thấy cái hàm nhan_xau_so bạn viết phức tạp quá: để nhân a cho m thì chỉ cần cộng a cho chính nó (m-1) lần là được rồi

Nói giỡn chút vậy thôi . Tui có thử tính 2^800 => tính khá nhanh
Tuy nhiên nếu tui tính 100 lần liên tiếp như vậy (bỏ vô vòng lặp) thì thấy mất khoảng 20 giây .

Viết như bạn là đạt yêu cầu rồi.
Nhưng tui thử sửa lại 1 chút => tính "2^800" 100 lần liên tiếp tốn khoảng 5 giây

Để tính a^1234 thì bạn cần làm 1233 phép nhân (a với chính nó)
Mình có thể làm ít phép nhân hơn như sau:

a^1234 = ((((((a^1)^10).(a^2))^10).(a^3))^10).(a^4)
=> sẽ cần làm khoảng (10+2+10+3+10+4) = 39 phép nhân

(điều này tương tự như: để tính a*1234 thì mình không cần làm tới 1234 phép cộng mà chỉ cần làm ít hơn nhiều)

Để tính lũy thừa với số mũ bất kỳ thì mình chỉ cần có 1 hàm để tính lũy thừa với số mũ nhỏ hơn hay bằng 10. Điều này cũng tương tự như: để làm phép nhần với 1 số bất kỳ thì mình chỉ cần có 1 hàm để làm phép nhân với 1 số nhỏ hơn hay bằng 9 (nhân với 10 thì quá dễ rồi cho nên không cần có 1 hàm)

Mình còn có thể làm nhanh hơn 1 chút nữa: để tính lũy thữa với số mũ nhỏ hơn hay bằng 10 => phân tích số mũ ra cơ số 2

(hiểu biết nông cạn; có gì sai sót mong được góp ý; xin cám ơn)

-thân

tallest299
02-01-2008, 00:52
phân tích một số ra thừa số nguyên tố
không biết đã ai biết chưa? mình mới tham gia 4rum mà:



program nguyento;
uses crt;
var i,n:integer;
S:char;
BEGIN
repeat
clrscr;
write('n:='); readln(n);
Write(n,'=');
while n>1 do
begin
i:=2;
while (n mod i) <>0 do
inc(i);
Write(i);
n:= n div i;
if n>1 then
write('*');
end;
Writeln;
Write('Co lam tiep hay khong?(Y/N)');
S:=readkey;
until S='n';
readln;



END.

Master_Baby
02-01-2008, 18:20
- Gửi mọi người :D:
Bi rờ chắc mọi người đều xài free pascal hết nhỉ -'___'-. Thi quốc gia cũng cho xài FP rồi. MB mới biết được một vài thủ thuật trong FP nè:
* Chú ý đặt định hướng biên dịch {$MODE OBCSFPC}
+ FP cho kiểu integer, cardinal thành 32 bit hết (trong TP thì là 16 bit). Khỏi lo về bộ nhớ, vì FP cho xài thoải mái (hổng có keo như TP ^^)
+ Thêm một minh chứng cho FP về tính hào phóng: FP có 2 kiểu dữ liệu xâu kí tự mới là AnsiString và WideString => cấu trúc động. Cũng giống như các ngôn ngữ hiện đại, 2 kiểu dữ liệu này lưu dưới dạng con trỏ. Khi gán a:= b thì trong TP sẽ copy xâu b ra đâu đó rồi bảo nó là a. Nhưng với 2 kiểu này thì đơn giản FP cho con trỏ a về chổ con trỏ b chỉ. Một câu hỏi đặt ra là nếu thay đổi a thì b có thay đổi theo không? Đương nhiên không, vì FP sẽ copy a ra đâu đó trước rồi mới sửa lại.
AnsiString là xài cho các kí tự ASCII, WideString xài cho cả unicode. Điểm đặc biệt ở FP là string được lưu như những mảng động, trừ kiểu string cũ. Cấp phát cho string ta dùng setLength. Ví dụ setLength cho a là 10 thì các kí tự trong a sẽ là a[0] đến a[9]. Cứ yên tâm mà xài, kiểu string cũ chỉ cho 255 ký tự còn AnsiString với WideString cho rất thoải mái, kích thước bộ nhớ tối đa cho 1 biến thuộc 2 kiểu này là.. 2GB ~___^ (yes, mắt bạn ko có vấn đề đâu. 2 gigabytelol).
Thêm một vấn đề là kích thước 2 kiểu string mới này đo như thế nào khi cấu trúc được dùng là mảng. Câu trả lời: dùng lệnh length như bình thường sẽ trả lại số phần tử, hoặc dùng lệnh high sẽ trả về index của phần tử lớn nhất. VD với xâu a đã được setLength là 10, thì length(a) trả về 10 còn high(a) trả về 9.
+ FP có cấu trúc lệnh khá giống try..catch..finally của java:


try
.
.
finally
.
.
end;



try
.
.
except
.
.
end;

Đặt các lệnh có khả năng gây lỗi vào sau try; những lệnh xử lý khi gây lỗi vào sau except; những lệnh mà có lỗi hay không có lỗi cũng "cố chạy" (ngang bướng ghê há ^^) vào trong finally.

P/s: Đổi chữ ký rồi ah cashier ^^

mr_invincible
02-01-2008, 21:26
Anh Master_Baby cho em hỏi luôn: em muốn tính xem chương trình của mình chạy trong Free Pascal thì làm như thế nào? (Trong Turbo Pascal em vẫn dùng lệnh absolute... để xem giờ nhưng không dùng được với Free Pascal) Em muốn tính ra giây nên nếu dùng GetTime rồi trừ theo giờ phút giây thì hơi tốn công. Em muốn hỏi có cách nào đơn giản hơn không?

truongngocdai
02-01-2008, 22:04
- Gửi mọi người :D:
Bi rờ chắc mọi người đều xài free pascal hết nhỉ -'___'-. Thi quốc gia cũng cho xài FP rồi. MB mới biết được một vài thủ thuật trong FP nè:
* Chú ý đặt định hướng biên dịch {$MODE OBCSFPC}
+ FP cho kiểu integer, cardinal thành 32 bit hết (trong TP thì là 16 bit). Khỏi lo về bộ nhớ, vì FP cho xài thoải mái (hổng có keo như TP ^^)
+ Thêm một minh chứng cho FP về tính hào phóng: FP có 2 kiểu dữ liệu xâu kí tự mới là AnsiString và WideString => cấu trúc động. Cũng giống như các ngôn ngữ hiện đại, 2 kiểu dữ liệu này lưu dưới dạng con trỏ. Khi gán a:= b thì trong TP sẽ copy xâu b ra đâu đó rồi bảo nó là a. Nhưng với 2 kiểu này thì đơn giản FP cho con trỏ a về chổ con trỏ b chỉ. Một câu hỏi đặt ra là nếu thay đổi a thì b có thay đổi theo không? Đương nhiên không, vì FP sẽ copy a ra đâu đó trước rồi mới sửa lại.
AnsiString là xài cho các kí tự ASCII, WideString xài cho cả unicode. Điểm đặc biệt ở FP là string được lưu như những mảng động, trừ kiểu string cũ. Cấp phát cho string ta dùng setLength. Ví dụ setLength cho a là 10 thì các kí tự trong a sẽ là a[0] đến a[9]. Cứ yên tâm mà xài, kiểu string cũ chỉ cho 255 ký tự còn AnsiString với WideString cho rất thoải mái, kích thước bộ nhớ tối đa cho 1 biến thuộc 2 kiểu này là.. 2GB ~___^ (yes, mắt bạn ko có vấn đề đâu. 2 gigabytelol).
Thêm một vấn đề là kích thước 2 kiểu string mới này đo như thế nào khi cấu trúc được dùng là mảng. Câu trả lời: dùng lệnh length như bình thường sẽ trả lại số phần tử, hoặc dùng lệnh high sẽ trả về index của phần tử lớn nhất. VD với xâu a đã được setLength là 10, thì length(a) trả về 10 còn high(a) trả về 9.
+ FP có cấu trúc lệnh khá giống try..catch..finally của java:


try
.
.
finally
.
.
end;



try
.
.
except
.
.
end;

Đặt các lệnh có khả năng gây lỗi vào sau try; những lệnh xử lý khi gây lỗi vào sau except; những lệnh mà có lỗi hay không có lỗi cũng "cố chạy" (ngang bướng ghê há ^^) vào trong finally.

P/s: Đổi chữ ký rồi ah cashier ^^


Lâu lâu mới vào box Pascal tí nhưng thấy nhắc đến Java là thấy máu liền à :w00t:

Cái ví dụ so sánh ở trên là sai rồi à nha :P :P :P
Ở trong Java thì là:


try
.
.
catch
.
.
finally
.
.

chứ :P :P :P
tức là ở đây thì "except" trong FP giống với "catch" trong Java

@Mà không biết cái gì trong FP thì giống với "finally" trong Java nhỉ

Master_Baby
14-01-2008, 12:51
- to mr_invisible:
Dùng getTickCount đi ^^. Đầu ct đặt a:= getTickCount rồi cuối ct write(getTickCount - a) {a: longint}
- to tnđ:
thì là finally chứ gì nữa ~^

jiSh@n
14-01-2008, 15:23
Lâu lâu mới vào box Pascal tí nhưng thấy nhắc đến Java là thấy máu liền à :w00t:

Cái ví dụ so sánh ở trên là sai rồi à nha :P :P :P
Ở trong Java thì là:


try
.
.
catch
.
.
finally
.
.

chứ :P :P :P
tức là ở đây thì "except" trong FP giống với "catch" trong Java

@Mà không biết cái gì trong FP thì giống với "finally" trong Java nhỉ
Phải ghép cả 2 cấu trúc try trong Object Pascal mới được cả cấu trúc try-catch-finally của java.

try
try
...
except
...
end;
finally
...
end;

mr_invincible
14-01-2008, 19:25
Hic, em chẳng hiểu gì cả
:dontgetit :dontgetit

likekiss
14-01-2008, 23:01
tôi có bài này bà con coi cố được không
đây là bài toán xếp hậu trên bàn cờ bà con có cách nào tốt hơn chỉ cho tui với nha
program tam_hau;
Uses Crt,Graph;
Const N=8; W=40; X=150; Y=400;
type mang=array[1..8] of byte;
var
a:mang;
i,k:integer;
ok:boolean;
{------------------------------------}
procedure ban_co;
Var Gd,Gm,i,j: Integer;
Pattern : FillPatternType;

BEGIN
Gd:=Detect;
InitGraph(Gd,Gm,'');
For i:=1 to N do
For j:=1to n do
Begin
If Odd(i+j) then SetFillStyle(SolidFill,01)
Else SetFillStyle(SolidFill,15);
Bar(X+(i-1)*W,Y-(j-1)*W,X+i*W,Y-(j)*W);
End;
end;
procedure hau(hi,hj:integer);
var i,j:integer;
Pattern : FillPatternType;
begin
SetColor(4);
Circle(X+(Hi-1)*W+W div 2,Y-(Hj-1)*W-W div 2,W div 2-5);
GetFillPattern(Pattern);
SetFillPattern(Pattern,4);
FloodFill(X+(Hi-1)*W+W div 2,Y-(Hj-1)*W-W div 2,4);
end;
{-----------------------------------------------}

procedure thuc_hien;
begin
k:=1; a[k]:=0;
while k>0 do
begin
a[k]:=a[k]+1;
ok:=false;
while (a[k]<=8) and (not(ok)) do
begin
i:=1;
ok:=true;
while (i<k) and ok do
if(a[i]<>a[k]) and (abs(a[i]-a[k])<>(abs(i-k))) then
inc(i)
else ok:=false;
if not ok then a[k]:=a[k]+1;
end;
if ok then
if k=8 then
begin
for i:=1 to 8 do
writeln;
ban_co;
for i:=1 to 8 do
begin
case a[i] of
1: hau(i,a[i]);
2: hau(i,a[i]);
3: hau(i,a[i]);
4: hau(i,a[i]);
5: hau(i,a[i]);
6: hau(i,a[i]);
7: hau(i,a[i]);
8: hau(i,a[i]);
end;

end;
readln;
clrscr;
end
else
begin
inc(k);
a[k]:=0;
end
else k:=k-1;
end;
end;
{-------------------------------}
begin
thuc_hien;
readln;
end.

likekiss
14-01-2008, 23:07
- Gửi mọi người :D:
Bi rờ chắc mọi người đều xài free pascal hết nhỉ -'___'-. Thi quốc gia cũng cho xài FP rồi. MB mới biết được một vài thủ thuật trong FP nè:
* Chú ý đặt định hướng biên dịch {$MODE OBCSFPC}
+ FP cho kiểu integer, cardinal thành 32 bit hết (trong TP thì là 16 bit). Khỏi lo về bộ nhớ, vì FP cho xài thoải mái (hổng có keo như TP ^^)
+ Thêm một minh chứng cho FP về tính hào phóng: FP có 2 kiểu dữ liệu xâu kí tự mới là AnsiString và WideString => cấu trúc động. Cũng giống như các ngôn ngữ hiện đại, 2 kiểu dữ liệu này lưu dưới dạng con trỏ. Khi gán a:= b thì trong TP sẽ copy xâu b ra đâu đó rồi bảo nó là a. Nhưng với 2 kiểu này thì đơn giản FP cho con trỏ a về chổ con trỏ b chỉ. Một câu hỏi đặt ra là nếu thay đổi a thì b có thay đổi theo không? Đương nhiên không, vì FP sẽ copy a ra đâu đó trước rồi mới sửa lại.
AnsiString là xài cho các kí tự ASCII, WideString xài cho cả unicode. Điểm đặc biệt ở FP là string được lưu như những mảng động, trừ kiểu string cũ. Cấp phát cho string ta dùng setLength. Ví dụ setLength cho a là 10 thì các kí tự trong a sẽ là a[0] đến a[9]. Cứ yên tâm mà xài, kiểu string cũ chỉ cho 255 ký tự còn AnsiString với WideString cho rất thoải mái, kích thước bộ nhớ tối đa cho 1 biến thuộc 2 kiểu này là.. 2GB ~___^ (yes, mắt bạn ko có vấn đề đâu. 2 gigabytelol).
Thêm một vấn đề là kích thước 2 kiểu string mới này đo như thế nào khi cấu trúc được dùng là mảng. Câu trả lời: dùng lệnh length như bình thường sẽ trả lại số phần tử, hoặc dùng lệnh high sẽ trả về index của phần tử lớn nhất. VD với xâu a đã được setLength là 10, thì length(a) trả về 10 còn high(a) trả về 9.
+ FP có cấu trúc lệnh khá giống try..catch..finally của java:


try
.
.
finally
.
.
end;



try
.
.
except
.
.
end;

Đặt các lệnh có khả năng gây lỗi vào sau try; những lệnh xử lý khi gây lỗi vào sau except; những lệnh mà có lỗi hay không có lỗi cũng "cố chạy" (ngang bướng ghê há ^^) vào trong finally.

P/s: Đổi chữ ký rồi ah cashier ^^

hic hay thế nhưng down nó ở đâu dấy bạn chỉ cho tui với được không cám ơn nhiều

lee_huynh306
14-01-2008, 23:29
@MasterBaby: Mình nhớ đi thi tin học thường thì cấm sử dụng các chỉ dẫn biên dịch mà, để {$...} vào là bị loại bài...

Master_Baby
15-01-2008, 12:34
- Gửi lee_huynh:

@MasterBaby: Mình nhớ đi thi tin học thường thì cấm sử dụng các chỉ dẫn biên dịch mà, để {$...} vào là bị loại bài...
Hì... Ngày xưa thôi huynh ơi, cái này là thầy Lê Minh Hoàng (thầy quá nổi tiếng rồi, chắc ai cũng bít nhỉ :) ) chỉ cho em đó.
Đi thi nên đặt try..except để đỡ mất test.
Chẳng hạn bộ test có 10 test (cùng 1 file), mà bị exception ở test 1 thì mấy test sau đáng lý vẫn có khả năng lấy điểm thì lại không có điểm (vì dính exception muh!)
Các kiểu dữ liệu lớn để xài dễ dàng hơn...
- Gửi likekiss:
Google đi bạn, nhanh không ấy muh :D.

mr_invincible
15-01-2008, 19:26
tôi có bài này bà con coi cố được không
đây là bài toán xếp hậu trên bàn cờ bà con có cách nào tốt hơn chỉ cho tui với nha

Không hiểu đây là bài vẽ tám hậu hay là tìm mọi cách xếp 8 quân hậu lên bàn cờ nhỉ? Nếu là bài xếp 8 hậu thì phải có quay lui kết hợp với nhánh cận chứ nhỉ?
To likekiss: bạn muốn biết down ở đâu thì vào google mà tìm

mr_invincible
16-01-2008, 21:03
Sau đây em xin giới thiệu với các bạn chưa biết một cách khá đơn giản để xác định xem chương trình chạy trong thời gian bao lâu (chỉ dùng với Turbo Pascal):
Phần khai báo biến thì thêm vào:
timer:longint absolute $0:$46c;
timeold:longint;
Trong chương trình chính:
begin
timeold:=timer;
{Thực hiện các lệnh của chương trình}
Writeln('Chương trình chạy trong ',(timer-timeold)/18.2,' giay');
Readln;
end.

Nhân tiện em xin hỏi luôn trong Free Pascal thì làm như thế nào? :dontgetit :dontgetit

blackcactus
18-01-2008, 22:34
Chương trình đo thời gian này có bị cấu hình máy chi phối không? Theo mình nghĩ, nếu muốn đo thời gian thì tốt nhất là tìm độ phức tạp của bài toán!

Master_Baby
19-01-2008, 08:37
- Gửi mr_invisible:
Thía này nè:


uses windows
var
a: longint;
begin
a:= getTickCount;
// các lệnh trong ct
writeln(getTickCount - a);
end.

Thời gian tính = milisecond(s)
- Gửi blackcartus:
Độ phức tạp của thuật toán thường chỉ được tính một cách tương đối thôi. Chẳng hạn như thuật toán tìm cặp ghép trọng số O(n^3) nhưng thực ra tính nhanh hơn rất nhiều.

m2mpro
27-01-2008, 07:11
- Gửi blackcartus:
Độ phức tạp của thuật toán thường chỉ được tính một cách tương đối thôi. Chẳng hạn như thuật toán tìm cặp ghép trọng số O(n^3) nhưng thực ra tính nhanh hơn rất nhiều.
Không tính độ phức tạp để mà ngồi gõ từng giải thuật rồi tính thời gian của nó à ! Tốn thời gian gấp đôi .

mr_invincible
28-01-2008, 16:09
Không tính độ phức tạp để mà ngồi gõ từng giải thuật rồi tính thời gian của nó à ! Tốn thời gian gấp đôi .

Độ phức tạp của các thuật toán được tính toán bằng toán học theo các phương pháp nhất định chứ không phải viết ra rồi tính thời gian đâu bạn ạ. Hơn nữa trong nhiều trường hợp người ta cũng chỉ tính độ phức tạp trung bình thôi. VD: độ phức tạp trung bình của Quick Sort là n log n nhưng trong trường hợp xấu nhất độ phức tạp vẫn lớn hơn

nhantt2
23-02-2008, 08:46
mấy anh ơi, post bài toán người du lịch lên cho em tham khảo với. (em nhỏ lớp 10)

mr_invincible
01-03-2008, 21:12
Post bài toán người du lịch tức là post thuật toán hay bài giải hay cái gì? Mà lớp 10 thì nhỏ gì?

TP2
03-03-2008, 10:18
Post bài toán người du lịch tức là post thuật toán hay bài giải hay cái gì? Mà lớp 10 thì nhỏ gì?

Post cả 2 đi bác...
Ôkê với bác, lớp 10 là lớn rồi nhỉ.

cashier
05-03-2008, 15:48
Bài toán người du lịch ???
Đây là bài toán tìm đường đi hay là bài toán xếp hành lí của người đi du lịch ??? Nói chung chung vậy khác j mò kim đáy bể :(

gon91
11-03-2008, 18:09
Cho em hỏi cách tìm số nguyên tố lớn nhất có thể?Và time test tối đa là
10s.

mr_invincible
11-03-2008, 21:28
Nếu là số lớn nhất có thể thì còn phụ thuộc vào may mắn. Chẳng hạn bạn bắt đầu tìm từ 10^100 thử xem :D, tất nhiên việc chọn số bắt đầu phụ thuộc vào may mắn, nếu bạn chọn mốc ban đầu ngay gần số nguyên tố thì ra ngay :D

hoangson88
20-03-2008, 21:47
ban ơi chỉ tớ cách kiểm tra ma trận với. Mãi mà ko hiểu đc Heplme

chungkid1
23-03-2008, 16:43
ban ơi chỉ tớ cách kiểm tra ma trận với. Mãi mà ko hiểu đc Heplme
Thứ khó hiểu ở đây là câu hỏi của bạn đó.Đọc chả hiểu gì cả

Cho em hỏi cách tìm số nguyên tố lớn nhất có thể
Đây là một bài toán phụ thuộc khá nhiều vào may măn.Nhưng cứ cố gắng đi,biết đâu bạn lại tìm được.Bạn ko tưởng tượng nổi một số nguyên tố lớn đáng giá bao nhiêu tiền đâu!

that_is_lg
30-03-2008, 16:39
mấy cái này ở sách giáo khoa tin học lớp 11 ban tự nhiên mà

tuananh3988
06-04-2008, 10:22
free pascal thì khác turbo ở điểm nào vậy?có nhiều cải tiến hơn ko?

langtusitinh225
12-04-2008, 20:34
Bạn nên xài Free Pascal vì nó tốt hơn rất nhiều so với Turbol/Borland Pascal.
Tốc độ nhanh hơn và có thể khai báo với số phần tử của mảng rất lớn (1.000.000 phần tử vẫn được, còn phụ thuộc vào thuật toán của bạn). Nhưng đổi lại thì dung lượng của nó khá lớn so với các phiên bản trước. Mình dùng mảng có thể tính được tới 100.000 giai thừa

vtnphong
17-04-2008, 15:25
Tôi có thắc mắc 1 tí.



Hàm inc() là hàm viết sẵn (structured function) cho pascal để thao tác trực tiếp với mã máy, vì vậy tôi không nghĩ rằng inc(i) lại chậm hơn i := i + 1; Trong trường hợp i := i + 1; compiler cũng phải dịch rồi xác định cái thằng "+" đó là dấu cộng rồi mới thực hiện phép tính.

inc() trong pascal chậm hơn bởi vì nó là lời gọi hàm. Khi gọi hàm thì phải thao tác trong stack búa xua nữa nên không nhanh như câu lệnh trực tiếp.

Thực ra thì cái này cũng chẳng quan trọng gì. Học pascal thì không nên quá chi li về mấy việc này như học assembly. Nên quan tâm về thuật toán tốt hơn là những trick về hệ thống.

ConanKudo
05-05-2008, 20:45
Nếu là số lớn nhất có thể thì còn phụ thuộc vào may mắn. Chẳng hạn bạn bắt đầu tìm từ 10^100 thử xem :D, tất nhiên việc chọn số bắt đầu phụ thuộc vào may mắn, nếu bạn chọn mốc ban đầu ngay gần số nguyên tố thì ra ngay :D

Ra ngay thế nào được em
Em thử kiểm tra hộ anh 10^56+3^134 có phải số nguyên tố không trong 1s xem nào em.
Hi,giờ người ta quan tâm nhiều đến thuật toán kiểm tra xem một số có phải số nguyên tố không hơn là tìm xem số lớn nhất(mặc dù nếu tìm được số nguyên tố lớn hơn cái số mà thế giới biết được thì đc ko ít money ) ,nhưng nếu chúng ta học để phục vụ thi cử thì không nên quan trọng cái này.
Thuật toán kiểm tra số nguyên tố tốt nhất mà anh được biết đến thời điểm này là thuật toán xác suất Rabbin - Miller

mr_invincible
22-05-2008, 09:44
Thuật toán kiểm tra số nguyên tố tốt nhất mà anh được biết đến thời điểm này là thuật toán xác suất Rabbin - Miller

Anh post lên luôn đi anh :D

Mr.Bo_Aloha
27-05-2008, 10:31
hix!!1 cho dù đã dc học pascal này khoảng 3 tháng. có 1 giải nhì hội thi tin học trẻ không chuyên về pascal của huyện phú quốc nhưng thú thật tui hiểu có một phần những gì các ông anh nói. quả thật la núi cao còn có núi cao hơn...chungkid1 à ông có thể cùng với mr_invincible... típ tục pót mấy cái pascal nhưng cụ thể 1 chút dc không. tui không hiểu nhìu về pascal nhưng làm sao ma đơn giản 1 chút thì tui rất cám ơn... xin chỉ giáo

[=========> Bổ sung bài viết <=========]

học pascal thì rất thú vị nhưng mà em có một thắc mắc ???
trong học đường thí vụ nhưng lớp 8 bọn em đã dc học pascal nhưng không bik cách ứng dụng.chỉ bik lập trình sau đó nhan Ctrl+f9 sau đó save để đó.

các sư phụ chỉ em làm sao ứng dụng nó vào trong thực tiễn. vd làm sao để đoạn code đó trở thành 1 chương trình sử dụng dc nhưng chương trinh word hoậc excel cua windown xp vậy

toadprince
28-05-2008, 09:31
Tôi nghĩ chúng ta có thể hoán vị hai số mà không cần biến trung gian(tiết kiệm bộ nhớ chút-hay đó):
"Đoạn trình cốt lõi của việc hoán vị a và b:"
begin
a:=a+b;
b:=a-b;
a:=a-b;
end;

Mr.Bo_Aloha
28-05-2008, 10:40
Tôi nghĩ chúng ta có thể hoán vị hai số mà không cần biến trung gian(tiết kiệm bộ nhớ chút-hay đó):
"Đoạn trình cốt lõi của việc hoán vị a và b:"
begin
a:=a+b;
b:=a-b;
a:=a-b;
end;

trong chương trinh của anh toadprince em nghĩ rất sáng tạo:

nếu theo cách đó là ta đã biến a thành a:=(a+b)-a => a sẽ có giá trị của b

và biến b thành b:= (a+b)-b vậy b cũng có giá trị của a
đây là cách áp dụng cộng thuật toán thông minh...

nhưng cẩn thận nếu không hiểu rõ thì sẻ dễ nhầm hơn so với cách dùng trung gian...

tiensusu
28-05-2008, 13:37
free pascal thì khác turbo ở điểm nào vậy?có nhiều cải tiến hơn ko?

Theo tôi thì Free Pascal hoàn toàn vượt trội so với Turbo
Bạn thử xem 1 ví dụ sau:
Var a:integer;
Begin
a:=20000;
write(a+a);
readln;
end.
Nếu chương trình này được chạy trên:
Turbo ==> kq:-25536
Free Pascal ==> kq:40000
Lý do: phép cộng này trên turbo bị tràn số. Như vậy khi làm bài trên turbo rất dễ bị sai khi thực hiện với số lớn
Ngoài ra Turbo còn gặp rất nhiều lỗi khác, bạn hãy tự tìm hiểu

song
29-05-2008, 13:22
chao` chung song muon' hoc pascal thi phai bat dau ra sao ?
giup minh nhe'
thanks

jiSh@n
29-05-2008, 13:33
Theo tôi thì Free Pascal hoàn toàn vượt trội so với Turbo
Bạn thử xem 1 ví dụ sau:
Var a:integer;
Begin
a:=20000;
write(a+a);
readln;
end.
Nếu chương trình này được chạy trên:
Turbo ==> kq:-25536
Free Pascal ==> kq:40000
Lý do: phép cộng này trên turbo bị tràn số. Như vậy khi làm bài trên turbo rất dễ bị sai khi thực hiện với số lớn
Ngoài ra Turbo còn gặp rất nhiều lỗi khác, bạn hãy tự tìm hiểu

Cái này ko phải là lỗi của Turbo Pascal mà là lỗi của bạn ;) Khi lập trình ko chỉ có thuật toán mà còn phải chú ý đến giới hạn kiểu dữ liệu của compiler đang sử dụng nữa.
Turbo Pascal là compiler 16bit, kiểu chuẩn integer có kích thước 16bit, việc cộng bị tràn là chuyện đương nhiên, bật Range checking lên bạn sẽ thấy Turbo báo lỗi. Trong khi đó FreePascal là trình biên dịch 32bit, kiểu integer có độ dài 4byte => phép cộng trên ko thể bị tràn.

tiensusu
29-05-2008, 22:19
Cái này ko phải là lỗi của Turbo Pascal mà là lỗi của bạn ;) Khi lập trình ko chỉ có thuật toán mà còn phải chú ý đến giới hạn kiểu dữ liệu của compiler đang sử dụng nữa.
Turbo Pascal là compiler 16bit, kiểu chuẩn integer có kích thước 16bit, việc cộng bị tràn là chuyện đương nhiên, bật Range checking lên bạn sẽ thấy Turbo báo lỗi. Trong khi đó FreePascal là trình biên dịch 32bit, kiểu integer có độ dài 4byte => phép cộng trên ko thể bị tràn.

Vậy thì theo jiSh@n thì với 2 cách làm sau đây tại sao ra kết quả khác nhau(trong Turbo):
1.Var a:integer;b:longint;
Begin
a:=20000; b:=0;
write(b+a+a);
readln;
end.
kq ==> 40000
2.Var a:integer;b:longint;
Begin
a:=20000; b:=0;
write(a+a+b);
readln;
end.
kq ==> -25536

jiSh@n
29-05-2008, 22:40
Vậy thì theo jiSh@n thì với 2 cách làm sau đây tại sao ra kết quả khác nhau(trong Turbo):
1.Var a:integer;b:longint;
Begin
a:=20000; b:=0;
write(b+a+a);
readln;
end.
kq ==> 40000
2.Var a:integer;b:longint;
Begin
a:=20000; b:=0;
write(a+a+b);
readln;
end.
kq ==> -25536
Trên các compiler thì kiểu của biểu thức sẽ là kiểu của toán hạng đầu tiên.
b+a => longint + integer => kiểu của kết quả sẽ là longint
a+b => integer + longint => kiểu kết quả là integer, bất chấp b là kiểu longint.

Hãy thử trên CodeGear Delphi 2007 cũng cho ra kết quả tương tự:


var a:integer; b:int64;
begin
a:=maxint; b:=maxint; // 2147483647
writeln(a+a+b); // 2147483645
writeln(b+a+a); // 6442450941
readln;
end.

mr_invincible
29-05-2008, 23:25
Phép toán trên không bị tràn số bởi vì Free Pascal định nghĩa integer giống như longint -> maxint là 2*10^9, vẫn chưa bị tràn. Do đó đây cũng không phải cải tiến gì mấy. VD: với kiểu longint 2*10^9 +2*10^9 vẫn tràn số như thường

[=========> Bổ sung bài viết <=========]


Tôi nghĩ chúng ta có thể hoán vị hai số mà không cần biến trung gian(tiết kiệm bộ nhớ chút-hay đó):
"Đoạn trình cốt lõi của việc hoán vị a và b:"
begin
a:=a+b;
b:=a-b;
a:=a-b;
end;

Các này mình cũng biết rồi nhưng thực sự thì các này không phải là cách hay bởi:
- Bộ nhớ tiết kiệm được quá ít, không có ý nghĩa trên thực tế (với kiểu số chỉ tiết kiệm được 6 hay 8 KB như thế thì không ăn nhằm gì so với những chương trình lớn dùng đến vài chục MB
- Cách làm trên không tổng quát (không thể dùng để đổi chỗ các kiểu phức tạp như mảng, xâu, kí tự...) hoặc nếu cố gắng làm thì khá rắc rối
- Dễ dẫn đến tràn số. VD: bạn thử đổi chỗ 2 số khoảng 2*10^9 theo các trên xem được không? -> các này không áp dụng được với nhiều trường hợp

tiensusu
30-05-2008, 17:53
Trên các compiler thì kiểu của biểu thức sẽ là kiểu của toán hạng đầu tiên.
b+a => longint + integer => kiểu của kết quả sẽ là longint
a+b => integer + longint => kiểu kết quả là integer, bất chấp b là kiểu longint.


Bạn đã thử chưa mà dám quả quyết như vậy, mình đã thử ví dụ này:


Var a:integer;b:longint;
Begin
a:=20000; b:=20000;
write(a+b);
readln;
end.

kq ==> 40000 (vượt quá giới hạn Integer)
Theo mình thì Pascal sẽ dựa vào biến lớn nhất trong biểu thức để tính toán, với những biến nhỏ hơn(byte) thì mặc định là Integer.
Theo như jiSh@n giải thích thì lỗi này là do compiler nhưng mình muốn hỏi tại sao không mặc định là longint cho nó khỏe, mình vẫn bảo thủ cho rằng lỗi này là do Pascal. Phần mềm nào mà chẳng bị lỗi, nhất là khi nó đã mười mấy năm rồi chưa được nâng cấp

jiSh@n
31-05-2008, 09:31
Bạn đã thử chưa mà dám quả quyết như vậy, mình đã thử ví dụ này:


Var a:integer;b:longint;
Begin
a:=20000; b:=20000;
write(a+b);
readln;
end.

kq ==> 40000 (vượt quá giới hạn Integer)
Theo mình thì Pascal sẽ dựa vào biến lớn nhất trong biểu thức để tính toán, với những biến nhỏ hơn(byte) thì mặc định là Integer.
Theo như jiSh@n giải thích thì lỗi này là do compiler nhưng mình muốn hỏi tại sao không mặc định là longint cho nó khỏe, mình vẫn bảo thủ cho rằng lỗi này là do Pascal. Phần mềm nào mà chẳng bị lỗi, nhất là khi nó đã mười mấy năm rồi chưa được nâng cấp

À, chỗ này mình nhầm 1 chút. Khi thực hiện phép toán giữa 2 toán hạng thì trình biên dịch sẽ tự động typecast kiểu của biểu thức sang kiểu của toán hạng lớn nhất, và thứ tự thực hiện các phép toán là từ trái sang phải theo độ ưu tiên toán tử. Lỗi chính xác phải là như thế này:
a+a+b => integer + integer + longint => (integer + integer) + longint => (integer + integer) bị tràn (40000) trước khi compiler typecast (integer+integer) sang kiểu longint để cộng với kiểu longint phía sau.

Cái này vốn dĩ ko phải là lỗi của trình biên dịch. Bạn thử bằng compiler mới nhất của Borland là CodeGear Delphi 2007 với kiểu integer (32bit) và int64 (64bit) sẽ thấy kết quả tương tự. Turbo Pascal ko thể dùng kiểu nguyên mặc định là longint (32 bit) vì nó là compiler 16 bit, kiểu nguyên mặc định của nó có độ dài 16 bit (integer), tương ứng 1 thanh ghi 16 bit (AX, BX, CX,...). Nếu bạn dùng compiler 32 bit (Delphi, Free Pascal 32) thì kiểu nguyên mặc định lúc này vẫn là integer nhưng có độ dài 32bit, tương ứng với 1 thanh ghi 32 bit (EAX, EBX, ...). Kiểu longint lúc này thực chất là 1 tên gọi khác của kiểu integer, và kiểu nguyên lớn hơn integer là int64 (64 bit). Tương tự, nếu bạn dùng compiler 64bit (chạy trên các OS 64bit - kiến trúc AMD64/EMT64) thì kiểu nguyên mặc định có độ dài 64bit.
Nếu bạn dùng Free Pascal 16 thì bạn cũng sẽ nhận được kết quả giống như Turbo Pascal, Turbo C hay các compiler 16bit khác thôi. Đây là lỗi do mã lệnh của lập trình viên, ko phải lỗi của compiler.

sugiathanchetbp
08-06-2008, 07:50
Mí anh chị ui! em mới là thành viên và sang năm em mới bắt đầu học lớp 11 thui
em chua học pascal bao giờ nên hôk piếc học làm sao để giỏi. Níu anh chị nào bik cách học thì chỉ em với nha! Thank nhìu nhìu lem'

[=========> Bổ sung bài viết <=========]

Thấy mí anh chị bàn luận sôi nổi ham ghê nhưng trình độ còn kém quá nên hôk dám góp ý
Tiếc thật!(T_T)

that_is_lg
12-06-2008, 09:14
Để phục vụ cho máy cái trò này tớ khuyên các bac dùng FPC là hơn cả
chọn options\ complier \ sau đó đóng dấu C_like operator
ta dùng uses crt, math;
ta được viết như sau i += 1; nó tương đương với i:= i+1; nhưng nhanh hơn vì nó chỉ bằng 1 phép gán 1 số cho 1 biến chứ không phải là phép tính.
Ngoài ra còn có -= /= *=
tiếp nữa để sắp xếp ta chỉ cần dùng hàm sort(); có sẵn
ngoải ra còn có 1 số hàm tìm max, min của cả mảng
Viết hoa cả chuỗi, viết thường cả chuỗi
Làm nhanh lém nhưng tui không nhớ rõ lắm ai cần thì Pm

jiSh@n
12-06-2008, 13:50
ta được viết như sau i += 1; nó tương đương với i:= i+1; nhưng nhanh hơn vì nó chỉ bằng 1 phép gán 1 số cho 1 biến chứ không phải là phép tính.


i:=i+1; i+=1; i++; inc(i);
Các compiler hiện đại đủ thông minh để biến các phép toán trên về dạng tối ưu, tốc độ như nhau thôi ;)

phoenixsinh
16-06-2008, 13:24
hi hi
phải là:
s:=s*i;
ứ hả?

[=========> Bổ sung bài viết <=========]

không biét có thể dùng cái này để tính số lần xuất hiện các kí tự trong một chuỗi ở một chuỗi khác không?
key:='loves';
ten:='vanduoc';
for i:= 1 to 5 do
begin
k[i]:=copy(key,i,1);
for j:=1 to 7 do
t[i]:=copy(ten,j,1);
if (k[i]=t[j] then
dem:=dem+1;
str(dem,tam);
insert(tam,so,[i]);

i hi mình mới nghĩ ra ngay tức thì nên có nhiều lỗi lắm, có những lỗi trầm trọng phải không?
i hi

htdang1981
04-07-2008, 07:21
minh moi buoc vao ngon ngu Lap Trinh

timberlake
09-07-2008, 10:05
Để use code
B1: tìm code
B2: copy code vào word ( save với tên *.doc) hay notepad( save với tên *.txt)
B3: kích hoạt PC mở tệp (đã lưu ở trên) save as thành tệp *.pas
B4: chạy chương trình.

magic1000
30-07-2008, 17:29
Sao mình học pascal mà thấy phát chán lên nhỉ.

huysun
23-08-2008, 11:56
hi hi
phải là:
s:=s*i;
ứ hả?

[=========> Bổ sung bài viết <=========]

không biét có thể dùng cái này để tính số lần xuất hiện các kí tự trong một chuỗi ở một chuỗi khác không?
key:='loves';
ten:='vanduoc';
for i:= 1 to 5 do
begin
k[i]:=copy(key,i,1);
for j:=1 to 7 do
t[i]:=copy(ten,j,1);
if (k[i]=t[j] then
dem:=dem+1;
str(dem,tam);
insert(tam,so,[i]);

i hi mình mới nghĩ ra ngay tức thì nên có nhiều lỗi lắm, có những lỗi trầm trọng phải không?
i hi

sao không dùng ngay hàm pos cho tiện???
for i:=1 to 5 do
if(pos(key[i],ten)<>0)then inc(dem);

lehuukyquan
06-11-2008, 08:40
Để đổi chỗ 2 phần tử - không nhất thiết dùng biến trung gian như sau:
a:=a+b;
b:=a-b;
a:=a-b;
Các bạn test lại, bảo đảm ok mà!
Thân ái!

tao_may_star_94
08-12-2008, 19:47
tôi có bài toán này muốn hỏi pà con tí nha
1) Cho 1 xâu kí tự hãy kiểm tra xâu đó có hoán vị không. Nếu không thì đảo xâu
2) Cho 1 dãy gồm các số bất kì và không hạn định, tính tổng các số dương liên tiếp. Sau đó tìm đọ dài của dãy đan dấu dài nhất( đan dấu là cứ 1 số âm rồi dương rồi âm rồi.....)
3) Cho 1 dãy số bất kỳ , không hạn đinh hãy tìm tổng con lớn nhất trong dãy đó

chooco_pie
14-12-2008, 17:13
chào mấy huynh nè, thế có ai nghĩ tới đồ họa trong pascal chưa ?, vẽ một cảnh đông quê thì sẽ như thế nào nhỉ? ai có code của một số cảnh thì cho mình tham khảo được không ?

BB_9x
12-01-2009, 08:55
..>.<
em mới học pascal ... khó wo'..
các bác ơi thuật toán sắp xếp ma trận tăng theo hàng và giảm theo cột viết thế nào?>.<.... giúp em với... thanks ..

huysun
13-01-2009, 12:27
..>.<
em mới học pascal ... khó wo'..
các bác ơi thuật toán sắp xếp ma trận tăng theo hàng và giảm theo cột viết thế nào?>.<.... giúp em với... thanks ..

đưa hết vào mảng 1 chiều, xếp theo chiếu tăng dần. sau đó cắt thành n mảng có n phần tử, rồi tự nghĩ tiếp.

khuon
20-01-2009, 08:19
- Gửi lee_huynh:

Hì... Ngày xưa thôi huynh ơi, cái này là thầy Lê Minh Hoàng (thầy quá nổi tiếng rồi, chắc ai cũng bít nhỉ :) ) chỉ cho em đó.
Đi thi nên đặt try..except để đỡ mất test.
Chẳng hạn bộ test có 10 test (cùng 1 file), mà bị exception ở test 1 thì mấy test sau đáng lý vẫn có khả năng lấy điểm thì lại không có điểm (vì dính exception muh!)
Các kiểu dữ liệu lớn để xài dễ dàng hơn...
- Gửi likekiss:
Google đi bạn, nhanh không ấy muh :D.


sao lại thế anh ơi :"try..except " là gì hả anh
anh có thể nói rõ hơn được ko

[=========> Bổ sung bài viết <=========]


Để đổi chỗ 2 phần tử - không nhất thiết dùng biến trung gian như sau:
a:=a+b;
b:=a-b;
a:=a-b;
Các bạn test lại, bảo đảm ok mà!
Thân ái!

hiển nhiên nhưng mà thêm 1 biến có tốn là bao,
phép gán tg:=a;a:=b;b:=tg; nhanh hơn nhiều so với phép cộng đó

phuthinh36
23-01-2009, 13:29
Tui nghĩ sau này bạn chungkid có thể sẽ thay đổi ý kiến về:

+Hãy thay câu lệnh inc(i) của bạn trong chương trình bằng câu lệnh i:=i+1.Vì sao à?Bởi vì câu lệnh sau tuy dài nhưng nó chạy nhanh hơn câu lệnh trước,ko tin hãy chạy mỗi cái khoảng 1 tỷ lần,bạn sẽ thấy nó khác như thế nào
(1 trình biên dịch tốt có đủ thông minh để dịch "inc(i)" giống y như "i:=i+1"
Cho dù "i:=i+1" có thiệt sự chạy nhanh hơn "inc(i)" đi nữa: xài đúng cấu trúc dữ liệu và thuật toán sẽ làm chương trình chạy nhanh hơn rất nhiều so với việc đổi "inc(i)" thành "i:=i+1")

+Thay vì viết (a) and (b),bạn hãy viết thế này
if a then
if b then
như thế nhiều khi có thể loại được một số bước xét ko cần thiết,làm chương trình có thể chạy nhanh hơn một chút.Hơn nữa có thể tránh một số lỗi vớ vẩn vì TP7 nhiều khi bị điên,viết (a) and (b) nó xét a đã sai rồi,nó xét b đúng nó vẫn chạy tiếp
(nếu bạn chắc chắn TP7 bị lỗi như vậy thì không nên xài nó làm gì !!!
Nhưng tui không biết bạn có lộn chỗ này hay không ? Tui nghĩ có thể là nó xét a sai rồi nó vẫn xét b tiếp; nhưng cuối cùng thì nó vẫn nhảy qua phần "else")

Nhưng cũng cám ơn bạn đã có ý tốt muốn chia sẻ kinh nghiệm

(hiểu biết nông cạn; có gì sai sót mong được góp ý; xin cám ơn)

-thân

Tán thành!
Khảo sát khi chạy 20000 lần thì inc(i) chạy lâu hơn i:=i+1 2s.
=> Khi chạy 1000000 lần thì inc(i) sẽ chạy lâu hơn i:=i+1 50s.

quantt
30-01-2009, 10:12
bác nào biết khử đệ qui(dùng vòng lặp) bài này giúp em với
Function F(k,n:byte):longint;
begin
if (k=0) or (k=n) then
F:=1
else
F:=F(k-1,n-1)+F(k,n-1)
end;
em cảm ơn các bác trước nhé

bi2005
06-03-2009, 14:02
em lạc đề một tí, vì em không biết forum nào sôi nổi và trả lời em ngay được, mong các anh giúp với
đề bài yêu cầu
nhap mảng một chiều từ file như sau
n
n phần tử
ví dụ:
5
1 3 5 6 2
xuất ra file nào đó.
các anh chỉ giúp em với

dongcambiz
09-03-2009, 21:34
em lạc đề một tí, vì em không biết forum nào sôi nổi và trả lời em ngay được, mong các anh giúp với
đề bài yêu cầu
nhap mảng một chiều từ file như sau
n
n phần tử
ví dụ:
5
1 3 5 6 2
xuất ra file nào đó.
các anh chỉ giúp em với

=>> xuất ra yêu cầu thế nào?

Squall_1701
22-04-2009, 01:03
ở cái bài cộng 2 số lớn, sao khi em dùng tệp để đọc dữ liệu vào (vd như 11 và 10) thì khi ở output nó lại ra là 11010.. em đã test với Writeln và Readln thì chương trình đọc bình thường.. ai chỉ cho em cách xóa dấu các để chương trình chạy đúng với. Cảm ơn.

[=========> Bổ sung bài viết <=========]

không ai giúp em à :((

Master_Baby
23-04-2009, 16:10
Chưa hiểu rõ trường hợp của bạn squall lắm :-? bạn có thể đem code lên đây không, vì chỉ có giúp thuật toán thì mới nói chay được thôi. Đằng này lại là lỗi vào ra dữ liệu?

kienanh04
22-05-2009, 18:40
Các anh giỏi quá.Giải hộ em bài pascan này.2 ngày nữa em báo cáo rùi:
6. Thông tin sách trong thư viện được lưu trong file thuvien.dat, gồm các trường: Mã sách, Tên sách, Tác giả, Năm xuất bản, Nhà xuất bản, Số trang, Giá tiền.
Viết chương trình kiểm tra xem file thuvien.dat đã tồn tại hay chưa? Nếu chưa tồn tại thì tạo file mới, ghi thông tin đầu sách. Nếu đã tồn tại thì ghi tiếp thông tin đầu sách vào file đó. Thực hiện các thao tác tìm, sửa, xóa với dữ liệu của một mã sách nào đó trong file.

nhat_truong
14-06-2009, 03:02
bác nào biết khử đệ qui(dùng vòng lặp) bài này giúp em với
Function F(k,n:byte):longint;
begin
if (k=0) or (k=n) then
F:=1
else
F:=F(k-1,n-1)+F(k,n-1)
end;
em cảm ơn các bác trước nhé

Hình như đây là hàm tìm tổ hợp C[k,n].
Bạn chỉ cần viết hàm tính giai thừa rồi dùng công thức:
C[k,n] = n! / (k!.(n-k)!)

quangtq
14-06-2009, 16:05
Hình như đây là hàm tìm tổ hợp C[k,n].
Bạn chỉ cần viết hàm tính giai thừa rồi dùng công thức:
C[k,n] = n! / (k!.(n-k)!)
@nhat_truong: Bác ấy êu cầu khử đệ quy mà anh.
Pác dùng pp QHĐ để khử thôi, bài này đơn giản, như ****naci ý mà.


Function CKN(k,n:integer):Longint;
Var F:array[0..101,0..101] of Longint;
i,j:integer;
Begin
F[0,0]:=1;
For i:=1 to n+1 do
For j:=1 to k+1 do
F[i,j]:=F[i-1,j-1]+F[i-1,j];
CKN:=F[n+1,k+1];
End;

Đúng ra có thể dùng 2 mảng 1 chiều cho đỡ tốn nhưng thôi ko sao.
Em mới nghĩ ra như thế, O((n+1)*(k+1)) có vẻ hơi phức tạp quá.
Có bác nào có cách đỡ hơn ko? (Ko dùng công thức n!/k!*(n-k)! đâu nha)

nhat_truong
15-06-2009, 17:12
@quangtq
QHD chẳng phải là đệ quy kết hợp với ghi nhớ sao, thế thì sao gọi là khử đệ quy được

hang_vt
15-06-2009, 20:58
@quangtq
QHD chẳng phải là đệ quy kết hợp với ghi nhớ sao, thế thì sao gọi là khử đệ quy được
cùng quan điểm =.=!
QHĐ và đệ quy về cơ bản có họ hàng với nhau : Phân bài toán đã cho thành các bài toán con kích thước nhỏ hơn và đã được giải quyết. Điểm khác biệt : Đệ quy không lưu lại bài toán con đã giải quyết, nên khi gặp lại thì nó tính lại như một bài toán hoàn toàn mới, trong khi đó quy hoạch động đã lưu bài toán con nên khi gặp thì nó đã có giá trị. (Từ điểm khác biệt này ta thấy được: do mất công tính lại nên đệ quy thường rất mất thời gian, còn QHĐ thì không, nhưng bù lại đệ quy thường không tốn bộ nhớ nhiều, trong khi QHĐ thì >_<, nên cách nào cũng có ưu khuyết cả)

quangtq
25-06-2009, 11:52
Ô thì em thấy pác kia bảo là dùng vòng lặp thì em lôi QHĐ ra. Mấy pác khử đi. Em chỉ biết thế thôi

mr_invincible
31-08-2009, 23:37
Đệ quy là khái niệm chương trình con gọi tới chính nó.
Khử đệ quy là viết sao cho không còn chương trình con nào gọi tới chính nó.
Quy hoạch động có nhiều cách viết, hoặc là for (hoàn toàn không đệ quy), hoặc là đệ quy, nhưng lưu lại giá trị, khi nào gọi đệ quy đến một trạng thái đã tính trước thì không tính lại nữa.

=> viết như quangtq là đúng rồi

quangtq
02-09-2009, 08:37
Hơ hơ. Anh RR ủng hộ. Thanks.
:D

technolt
07-09-2009, 19:44
Một vấn đề khác liên quan đến C(k,n):
Tính ước chung lớn nhất của C(1,n) -> C(n-1,n)
@RR: anh biết CM cách giải của nó ko?

mylinh9006
16-10-2009, 09:32
bạn ui mình nhờ bạn giúp chút việc nhé
mình muốn viết 1chương trình sử dụng unit. các chương trình con là, chuvitamgiac, chuvihinhchunhat, chuvitron, dientichtamgiac, dientichhinhchunhat, dientichtron .lưu với đuôi .TPU mình hok làm được bạn có biết thì bớt chút thời gian chỉ cho mình nhá.sẽ rất cảm ơn bạn

chung49dhv
07-11-2009, 14:54
Mấy phác giúp em mấy câu này cái
Câu1 : Sử dụng Repeat... Until để tính tổng S=1+1/2+1/4...+1/(2n).Với n nguyên dương được nhập từ bàn phím. Yêu cầu chương trình có kiểm tra tính hợp lệ
Câu 2 : Sử dụng While.... do để tính tổng S= 2+5...+(3n-1).Với n nguyên dương được nhập từ bàn phím. Yêu cầu chương trình có kiểm tra tính hợp lệ
Cẩu 3 : Viết chương trình tính tổng S=1-1/2+1/3+...+(-1)mũ n+1/n.Với n nguyên dương được nhập từ bàn phím. Yêu cầu chương trình có kiểm tra tính hợp lệ
Câu 4: Viết chương trình tính tổng
S= 2002+2+4+....2n
Với n nguyên dương được nhập từ bàn phím. Yêu cầu chương trình có kiểm tra tính hợp lệ
Câu 5:Viết chương trình nhập vào một số nguyên dương n, kiểm tra xem số đó có phải nguyên tố hay không
Câu 6: Viết chương trình tính và in ra n, với n nguyên dương ( n<=7) được nhập từ bàn phím.Yêu cầu chương trình có kiểm tra tính hợp lệ.
Câu 7: Viết chương trình cho phép nhập vào 1 số thực a ( 1<a<10). Hãy tìm số n nguyên dương nhỏ nhất sao cho 1+1/2+...1/n>= a.
Câu 8: Hãy viết chương trình tìm tất cả các số nguyên dương có 3 chữ số sao cho:
___ 3 3 3
abc= a +b +c [ a mũ 3 , b mũ 3 c mũ 3).

hungkcdhv
10-11-2009, 21:41
Bạn nói rõ hơn về các kiểm tra tính vi phạm đi ?

tomatoxanh
15-12-2009, 22:26
Câu1 : Sử dụng Repeat... Until để tính tổng S=1+1/2+1/4...+1/(2n).Với n nguyên dương được nhập từ bàn phím. Yêu cầu chương trình có kiểm tra tính hợp lệ
Bài giải:
Var n,i:Integer;
S:real;
Begin
Repeat
write('Nhap so nguyen duong n: ');readln(n);
Until n>0;
S:= 1; i := 1;
Repeat
S:= S + 1/(2*i);
i:=i+1;
Until i>n ;
Writeln('Tong S = ',S:10:2);
Readln;
END.

[=========> Bổ sung bài viết <=========]


Câu1 : Sử dụng Repeat... Until để tính tổng S=1+1/2+1/4...+1/(2n).Với n nguyên dương được nhập từ bàn phím. Yêu cầu chương trình có kiểm tra tính hợp lệ
Bài giải:
Var n,i:Integer;
S:real;
Begin
Repeat
write('Nhap so nguyen duong n: ');readln(n);
Until n>0;
S:= 1; i := 1;
Repeat
S:= S + 1/(2*i);
i:=i+1;
Until i>n ;
Writeln('Tong S = ',S:10:2);
Readln;
END.

Các bạn đưa nhiều bài tập nữa đi để mọi người tham khảo học tập

kien_sph
02-01-2010, 03:02
cho tui hoi loi 109 trong passcal la loi ji vay

[=========> Bổ sung bài viết <=========]

co ban nao joi jup tui voi
tui cam on nhieu

laptop943hongha
14-01-2010, 16:24
có ý kiến với chủ toppic đây là :1 số kĩ thuật cơ bản cua pascal cơ mà sao các bác toàn nói cao xa thía chẳng trách lắm lỗi xin hãy post các bài cơ bản nhưng không thể thiếu Như TÍNH TỔNG,TÍNH SỐ TRUNG BÌNH, TÍNH GIÁ TRỊ MAX,MIN cho mọi người mới bắt đầ với pascal có dịp học hỏi không chie học trên lớp thôi chụt hết.
Tiện thể cho em hỏi 1 vấn để em có 1 bài tấp sau :Cho danh sách liên kết đơn có con trỏ là L,mỗi nút chứa 1 số khác không. Lập giải thuật đếm số lượng các số trong danh sách.Sau khi tìm hiểu đề gặp đc 1 đoạn mã viết về giải thuật trên nhưng vấn đề em học pas chưa đc học C nên ko hiểu rõ vậy mong bác nào chỉnh sửa cho nó về ngôn ngữ mẹ để hộ em với
Chỉnh về pascal ạ
đoạn mã về giải thuật trên trong C:
int DemSoNode(DanhSach a)
{
int Dem=0;
Nut* q = a.NutDau;
while (q!=NULL)
{
Dem++;
q=q->Tiep;
}
return Dem;
}
http://ddth.com/showthread.php?t=331794
Mong mọi người giúp đỡ gấp

nirvanat
22-01-2010, 19:34
Tiếp nhé
+Hàm kiểm tra số nguyên tố,trả về true nếu số n là số nguyên tố
[code]
Function nt(n:integer):boolean;
Var
i:integer;
Begin
if n<=1 then begin
nt:=false;
Exit;
end;
for i:=2 to (n div 2) do
if (n mod i)=0 then begin
nt:=false;
Exit;
end;
nt:=true;
End;

Bác ji` ji` đó trong ddth vừa đưa ra cách tìm nhanh hơn nè. trích dẫn lại cho các bác các cô ^^!.
If k<2 then kt:=false
else if (k=2)or (k=3) then kt:=true
else If (k/6+1 mod 1=0)or (k/6-1 mod 1=0) then kt:=true;
Nghĩa là ngoài số 2 và 3 là 2 số nguyên tố, tất cả các số nguyên số sau đều có dạng 6k+(-)1 {k=1,2,...). viết như trên kia không bek có đúng không, ai kiểm tra giùm tui nha ^^!

o0Tieu0Long0o
01-03-2010, 22:49
Nếu nói inc(i) nhanh hay chậm hơn i:=i+1 thì dù có cái nào nhanh hay chậm thì cũng đâu đáng kể, chạy 1 tỉ lần mới nhận thấy sự khác biệt, trong khi có ct nào chạy i 1 tỉ lần không? Hiếm lắm mới có 1 bài như thế, trong khi thời gian tiết kiệm được chẳng là bao.

[=========> Bổ sung bài viết <=========]


Bác ji` ji` đó trong ddth vừa đưa ra cách tìm nhanh hơn nè. trích dẫn lại cho các bác các cô ^^!.
If k<2 then kt:=false
else if (k=2)or (k=3) then kt:=true
else If (k/6+1 mod 1=0)or (k/6-1 mod 1=0) then kt:=true;
Nghĩa là ngoài số 2 và 3 là 2 số nguyên tố, tất cả các số nguyên số sau đều có dạng 6k+(-)1 {k=1,2,...). viết như trên kia không bek có đúng không, ai kiểm tra giùm tui nha ^^!

Đây là tính chất ít được biết đến của số nguyên tố đó bạn, yên tâm tính chất này đúng.

tomatoxanh
13-03-2010, 12:40
Bác ji` ji` đó trong ddth vừa đưa ra cách tìm nhanh hơn nè. trích dẫn lại cho các bác các cô ^^!.
If k<2 then kt:=false
else if (k=2)or (k=3) then kt:=true
else If (k/6+1 mod 1=0)or (k/6-1 mod 1=0) then kt:=true;
Nghĩa là ngoài số 2 và 3 là 2 số nguyên tố, tất cả các số nguyên số sau đều có dạng 6k+(-)1 {k=1,2,...). Có ai chứng minh tính chất này để mọi người cùng học tập với!

letrungcuongdtc
05-06-2010, 16:27
kiem tra nguyen to theo e chach nay le the best:

for i:=2 to trunc(sqrt(N)) do if N mod i=0 then
begin
kt:=false;
exit;
end;

[=========> Bổ sung bài viết <=========]

anh+chi nao biet chia keo cho N nguoi k?em chi biet chia cho 2 nguoi ah,k man nguyen.chiua cho N nguyoi ta dung thuat toan "sinh nhị phân"

nếu day co M phan tu thi vong for se chay 2^N-1;
cach tao day "sinh nhị phân" :
for i:=1 to M do
if S[i]='0' then {S la kieu string}
begin
S[i]:='1';
for j:=i+1 to M do S[j]:='0';
break;
end;
Lê Trung Cường hst Đặng Trần Côn

[=========> Bổ sung bài viết <=========]

ua sao co space ma no van thang duot vay troi

gyghung
01-09-2010, 08:08
bảng mã ASCII

program gyg;
uses crt;
var I:integer;
begin
clrscr;
for I:=0 to 255 do
write(I,'=', CHR(I),'');
readln;
end.

nguyenthong1593
14-11-2010, 22:31
program fibonaci;{c/trinh tim so Fibonaci thu n}
uses crt;
var n,i: integer;fi1,fi2,fi3 :longint;
begin
clrscr;
write('nhap so n = ');readln(n);
fi1:=1; fi2:=2; fi3:=fi1 + fi2 ;
if(n=1) or (n=2) then writeln('so fibonaci thu ',n,' = 1')
else
for i:= 3 to n do
begin
fi1:= fi2;
fi2:= fi3;
fi3:= fi1 + fi2;
end;
writeln('so fibonaci thu ',n,' = ',fi3);
readln;
end.
hjhj có gì không đúng thì mong các bác bỏ qua cho em nha! hjhj

nazcy
11-03-2011, 23:06
Function GT(x,y:integer):Longint;

cái này là gì hả bạn, có bắt buộc phải dùng không. tớ chưa bao giờ dùng " function" nên không biết

lendoixyz
12-03-2011, 19:58
hi mình mới học pascal nhưng toàn dùng để giải toán mình chẳng hiểu gì cả ai có thể hướng dẫn cho mình từng bước 1 để học pascal được pro ko ^^
Yh: upanhx

kh1132000
31-03-2011, 11:32
Giup mính sửa đoạn code này với.


program kyphapnghichdao;
type kieu_stack =array[1..80] of 0..1;
var BT:string[30];
S: kieu_stack;
Top,i,so1,so2,n,x:integer;
procedure PUSH(var s:kieu_stack;var Top:integer;x:integer);
begin
if Top:=n then
writeln('s khong con cho trong');
else
begin
Top:=Top+1;
S[Top]:=x;
end;
end;
function POP(var s:kieu_stack; var Top:integer; x:integer):integer;
begin
if Top>0 then
begin
POP:=S[Top];
Top:=Top-1;
end;
else
writeln('stack day');
end;
function tinh_BT(BT:string):real;
begin
for i:=1 to length(BT) do
begin
case BT[i] of
'+':begin
so1:= POP(s, Top);
so2:= POP(s, Top);
PUSH(s,Top, so1+so2);
end;
'-':begin
so1:=POP(s, Top);
so2:=POP(s, Top);
PUSH(s,Top, so1-so2);
end;
'*':begin
so1:=POP(s, Top);
so2:=POP(s, Top);
PUSH(s,Top, so1*so2);
end;
'/':begin
so1:=POP(s, Top);
so2:=POP(s, Top);
PUSH(s,Top, so1/so2);
end;
slse
begin
val(BT[i],n,e);
PUSH(s,Top,n);
end;
end;
Tinh_BT:=POP(s,Top);
end;
BEGIN
write('nhap BT hau to:');
readln(BT);
writeln('tinh BT=',Tinh_BT(BT));
END.

tho ngok
01-04-2011, 00:05
[/code]
+Sắp xếp mảng a với n phần tử theo thứ tự tăng dần,sử dụng thuật toán Bubble Sort


Procedure BubbleSort(Var a:mang,n:integer);{Mang là kiểu array khai báo
bằng từ khóa Type}
Var i,j:integer;
Begin
for j:=1 to n-1 do
for i:=n downto j+1 do
if a[i]<a[i-1] then
Swap(a[i],a[i-1];{Thủ tục Swap ở trên})
End;


xin lỗi
mh là member mới vào nghề nên củ chuối lắm
bạn có thể chỉ cho mh cái 'thủ tục swap' trên dk k??
chắc trên phần khai báo phải có thêm cái j liên quan đến swap phải k nạk
bạn đừng cười nha
:">

[=========> Bổ sung bài viết <=========]


cho tui hoi loi 109 trong passcal la loi ji vay

[=========> Bổ sung bài viết <=========]

co ban nao joi jup tui voi
tui cam on nhieu

hình như sau phụ lục SGK lớp 11 có bạn ạk
mh nhác đi tìm sách nữa nên bạn chịu khó nha
xl bạn

auauau97
18-06-2011, 18:33
Tiếp nhé
+Hàm kiểm tra số nguyên tố,trả về true nếu số n là số nguyên tố


Function nt(n:integer):boolean;
Var
i:integer;
Begin
if n<=1 then begin
nt:=false;
Exit;
end;
for i:=2 to (n div 2) do
if (n mod i)=0 then begin
nt:=false;
Exit;
end;
nt:=true;
End;

+Hàm tính giai thừa(loại cơ bản,áp dụng cho số nguyên dương n<=15)


Function gt(n:byte):Longint;
Var
s:Longint;
i:byte;
Begin
s:=1
For i:=2 to n do
s:=s*i;
gt:=s;
End;

+Sắp xếp mảng a với n phần tử theo thứ tự tăng dần,sử dụng thuật toán Bubble Sort


Procedure BubbleSort(Var a:mang,n:integer);{Mang là kiểu array khai báo
bằng từ khóa Type}
Var i,j:integer;
Begin
for j:=1 to n-1 do
for i:=n downto j+1 do
if a[i]<a[i-1] then
Swap(a[i],a[i-1];{Thủ tục Swap ở trên})
End;

Phương pháp này chạy chậm với những bộ dữ liệu lớn,vì vậy khi cần phương pháp sắp xếp tốt hơn,bạn nên dùng phương pháp Quick sort.Chương trình của nó có sẵn trong thư mục Example của Pascal,là file QSort.pas.Tuy nhiên bạn nên nhớ lấy để dùng,ko nên quá ỷ lại vào chương trình có sẵn,rủi bị ai xóa mất thì chỉ có khóc thôi


.Chương trình của nó có sẵn trong thư mục Example của Pascal,là file QSort.pas
Cái chỗ thư mục Example là ở chỗ nào thế bạn, sao tp7 của mình không có nhỉ ?
Có gì sai sót xin anh em bỏ qua nhé !

[=========> Bổ sung bài viết <=========]

Hàm tính USCLN của 2 số :

Function USCLN(a,b:integer):integer;{Ham tim USCLN cua 2 so}
Begin
If a<0 then a:=-a;
If b<0 then b:=-b;
While (a<>0) and (b<>0) do
If a>b then a:=a mod b
Else b:=b mod a;
USCLN:=a+b;
End;

auauau97
16-08-2011, 16:24
cái này là gì hả bạn, có bắt buộc phải dùng không. tớ chưa bao giờ dùng " function" nên không biết
Không bắt buộc phải dùng đâu bạn !

horseman194
06-10-2011, 20:58
ban auauau9 oi làm giúp mình bài này vs. Viết 1 code hoàn chỉnh lun nha
Viết chương trình khai báo một chuỗi có chiều dài 50 kí tự.
Viết chương trình sinh các kí tự ngẫu nhiên trên chuỗi đó. Biết các số thứ tự từ A->Z là 65->90

auauau97
08-10-2011, 18:31
ban auauau9 oi làm giúp mình bài này vs. Viết 1 code hoàn chỉnh lun nha
Viết chương trình khai báo một chuỗi có chiều dài 50 kí tự.
Viết chương trình sinh các kí tự ngẫu nhiên trên chuỗi đó. Biết các số thứ tự từ A->Z là 65->90
Đã có bạn trả lời hộ bạn trong topic này rồi mà:
http://www.ddth.com/showthread.php/868486-gi%C3%BAp-em-b%C3%A0i-t%E1%BA%ADp-pascal-vs


Uses crt;
Var
chuoi:string[50];
i:integer;
BEGIN
Clrscr;
Randomize;
For i:=1 to 50 do
chuoi[i]:=chr(random(25)+65);
Writeln('Chuoi ky tu ngau nhien la :');
For i:=1 to 50 do write(chuoi[i]);
Readln;
END.

Em Chán Gà
18-11-2011, 13:08
Một số kỹ thuật nên dùng:
- Xây dựng một thư viện riêng với các hàm - thủ tục thường xuyên sử dụng
- Nguyên tắc đặt tên biến: Hoặc quy ước các chữ cái cho từng loại biến, hoặc dùng biến gợi nhớ.
- Để gọi help của một lệnh, hàm có sẵn, bôi đen tên của lệnh, hàm (có thể gõ gần đúng)... rồi nhấn CTRL + F1.
-

kickbuttowski
16-02-2012, 17:08
co ai biet lam bai pascal nay ko?
tim tong cua tat ca cac so nguyen to tu 1 den 100 (dung menh de if , cau lenh while do va for to do)

venus.tt9x
03-03-2012, 22:38
co ai biet lam bai pascal nay ko?
tim tong cua tat ca cac so nguyen to tu 1 den 100 (dung menh de if , cau lenh while do va for to do)
tạo function kiểm tra ntố, rồi kiểm tra từ 2 đến 100. nếu i là n tố thì cộng thêm i vào s


program nt;
var s:integer;
function nt(x:byte):boolean;
var i,d:byte
begin
for i:=2 to trunc(x) do
if x mod i =0 then inc(d);
nt:=(d=0);
end;

BEGIN
for i:=2 to 100 do
if nt(i) then s:=s+i;
writeln('tong can tih la',s);
readln;
END.

shadow waker
07-03-2012, 11:26
mai mình phải nộp bài rùi các bạn giúp mình với không có bài là die mình đó:((. thanks mọi người!!


Bài số 1: Hãy xác định số tiền vay, trả và hạn mức tín dụng trong 6 tháng đầu năm 2011 của công ty ABC dựa trên bảng số liệu sau:
Tháng 1 2 3 4 5 6
1. Tổng thu trong kỳ 200 200 250 300 350 400
2. Tổng chi trong kỳ 230 280 320 360 190 200
3. Ngân lưu ròng
4. Số dư tiền đầu kỳ 10
5. Thặng dư/thâm hụt
6. Số dư tiền tối thiểu 15 15 15 15 10 10
7. Vay (+)/ Trả (-) trong kỳ
8. Dư nợ vay cuối kỳ
9. Hạn mức tín dụng

Biết rằng:
 Ngân lưu ròng = Tổng thu trong kỳ - Tổng chi trong kỳ
 Số dư tiền đầu kỳ = Số dư tiền cuối kỳ của kỳ trước
 Thặng dư / Thâm hụt = Số dư tiền đầu kỳ + Ngân lưu ròng
 Vay / trả trong kỳ:
 Nếu thâm hụt: Vay/trả trong kỳ = Số dư tiền tối thiểu - Giá trị thâm hụt
 Nếu thặng dư và giá trị thặng dư lớn hơn số dư tiền tối thiểu: Vay/trả trong kỳ = Giá trị thặng dư - Số dư tiền tối thiểu. Ngược lại: Vay trả trong kỳ = Số dư tiền tối thiểu – giá trị thặng dư trong kỳ
 Hạn mức tín dụng = max(hạn mức tín dụng tháng i (với i = 1..6))
Yêu cầu:
1. Hãy xuất ra thông tin chi tiết của 6 tháng đầu năm 2011.
2. Hãy tìm và xuất ra thông tin của tháng có giá trị thặng dư lớn nhất, giá trị thâm hụt lớn nhất.
3. Hãy xuất ra thông báo cho nhà tín dụng biết hạn mức tín dụng tính được từ các dữ liệu cho trên là bao nhiêu?
4. Hãy xuất ra thông tin của các tháng theo thứ tự tăng dần của ngân lưu ròng.
5. Hãy xuất ra thông tin của các tháng theo thứ tự giảm dần của dư nợ vay cuối kỳ.
6. Hãy nhập thêm vào bảng dữ liệu cho sẵn cột tháng 7 với giá trị tổng thu trong kỳ là 450, tổng chi trong kỳ 480. Hãy xuất ra thông tin của 7 tháng đầu năm 2011.

ahnioht
23-03-2012, 14:05
ai biết đoan chương trình này không .bao mình hiểu cái
program da;
uses crt;
Var
P:real;Y:byte;
Const
W = 208.3; a = 100;
procedure tieude;
begin
textbackground (1);
textcolor(7);
gotoxy(30,5);
writeln('DO LUC VA UNG SUAT');
gotoxy(20,25);
writeln('Copyright by HA THANH LAM - PHAM TRONG QUYNH ');
end ;
procedure docdulieu;
var X1,X2,X:byte;
begin
port[$378] := $03;
port[$378] := $13;
port[$378] := $33;
port[$378] := $23;
port[$378] := $03;
repeat
X:= port[$379] and $08
until X = $08;
X1:= ((port[$379] SHR 4) XOR $08);
port[$378] := $0B;
X2:= ((port[$379] AND $F0) XOR $80);
Y:= X1 OR X2;
delay(1000);
end;
Procedure LUC;
Var
g:real;
Begin
g:=7.84;
p:=y*g;
gotoxy(20,7);
writeln('LUC : P = ',p:8:3, ' gram');
End;
Procedure UNGSUAT;
Var
sigma:real;
Begin
sigma:= (p*a)/W;
gotoxy(19,9);
write(' UNG-SUAT : Sigma = ',sigma:8:3, ' gram/mm^2');
End;
Procedure BIENDANG;
Var
epsilon,e : real;
Begin
e:=5000;
epsilon:=(p*a)/(w*E);
gotoxy(20,11);
write('BIEN-DANG : Epsilon = ', epsilon:8:3, ' us');
End;
Procedure OFFSET;
Var
X:real;
Begin
Repeat
docdulieu ;
gotoxy(20,5);
writeln(X);
delay(10000);
gotoxy(20,5);
writeln(' ');
Until Upcase(readkey) = 'N';
End;
{================CHUONG TRINH CHINH===================}
BEGIN
CLRSCR;
tieude;
repeat
docdulieu;
luc;
ungsuat ;
biendang;
delay(10000);
delay(1500);
until keypressed;
END.

Brantanna
23-03-2012, 15:46
Chương trình này chạy trên máy tính có kết nối với một mạch điện tử qua cổng song song (parallel) để đọc dữ liệu vào tương ứng với các byte điều khiển xuất ra từ máy tính và tính toán lực, ứng suất, độ biến dạng rồi xuất kết quả ra màn hình.

Brantanna
23-03-2012, 21:17
@ahnioht: Bạn nhắn tin PM hỏi, nhưng vấn đề là bạn không nói là bạn có biết gì về Pascal hay Delphi hay không, và hỏi rất chung chung nên cũng không biết trả lời thế nào. Mình sẵn sàng hướng dẫn những gì mình biết nhưng cũng phải biết là bạn biết được gì rồi. Vậy nhé! :)

ahnioht
24-03-2012, 22:41
rất mong bạn có thể giúp mình

anhhoacuc
16-07-2012, 06:37
Program so6cs;
Uses Crt;
Var a,dv,ch,n,ng,u,v,tr,dem,dem2,schan,k,sle,i:longint ;l:integer;
Begin
Clrscr;
Write('Nhap so n:');
Readln(n);
u:=n div 100000;
v:=n div 10000;
v:=v mod 10;
ng:=n div 1000;
ng:=ng mod 10;
tr:=n div 100;
tr:=tr mod 10;
ch:=n div 10;
ch:=ch mod 10;
dv:=n mod 10;
{Write(u,' ',v,' ',' ',ng,' ',tr,' ',ch,' ',dv);}
Sle := 0;
schan:=0;
a:=n;
For l:=1 to 6 do
Begin
k := N mod 10;
If k mod 2 <>0 then
begin
N := N div 10;
if k mod 2 <> 0 then
Sle := Sle + k;
end
Else
Begin
i := a mod 10;
a := a div 10;
if i mod 2 = 0 then
schan := Schan + i;
end;
Writeln( 'Tong cac chu so chan la :', Schan);
Writeln( 'Tong cac chu so le la :', Sle);
Readln;
end;
end.

JeremyBelpois
31-10-2012, 20:33
Bạn anhhoacuc viết có lẽ là sai phần Begin end, với lại thuật toán này viết quá dài, khó hiểu. mình có cách khác nhanh hơn:


Program so6cs;
Uses Crt;
Var n:longint;
k,tle,tchan:integer;

begin
write('NHAP N : ');readln(n);
tle:=0;
tchan:=0;
while n>0 do
begin
k:=n mod 10;
if k mod 2 = 0 then tchan:=tchan+k else
tle:=tle+k;
n:=n div 10;
end;
writeln('Tong cac chu so le : ',tle);
writeln('Tong cac chu so chan : ',tchan);
readln;
end.

ada95
11-11-2014, 13:26
1. Trong chương trình, 01 đoạn lệnh nào đó (có thể là 01 chương trình con-procedure hay function), nếu chỉ chương trình trên của nó dùng - tạm gọi là chương trình mẹ (ví dụ: tính delta trong GPT bậc 2), thị nó nên là đoạn lệnh (hoặc CT con) nằm lồng trong CT mẹ;

Nếu thấy nó có thể được sử dụng bởi trong nhiều CT khác nhau (ví dụ: hàm Sin, Cos ...), thì ta nên đưa nó vào 01 thư viện dùng chung (vd: MATH TPU).

2. Giữa tên procedure/function với tham số của nó (nếu có), giữa các tham số: nên để cách 01 khoảng trắng/ hoặc 01 Tab cho dễ nhìn/ dễ đọc/ dễ chỉnh sửa sau này.

Ví dụ:


procedure BufferToFile (pBuffer :pointer; dFile :string; Size :longint);
var
vFile :file;
begin
Assign (vFile, dFile);
ReWrite (vFile, 1);
BlockWrite (vFile, pBuffer^, Size);
Close (vFile);
end;


3. Đối với từ khóa (từ khóa: chung, khai báo, điều khiển, lặp, toán tử, lựa chọn...):
- Trong chương trình con nên viết hoàn toàn bằng chữ thường;
- Trong chương trình chính nên VIẾT HOA các từ khóa:
PROGRAM, BEGIN, END, TYPE, VAR, LABEL, CONST
(Kể cả hằng, như: CONST PI = 3,1516926).

4. Đối với khai báo Kiểu, biến, nhãn, hằng (TYPE, VAR, LABEL, CONST): nếu chỉ có 1 thì để cùng hàng với từ khóa; từ 2 trở lên thì cho xuống hết từng dòng một.
Nên khai báo từng dòng cho từng biến, kể cả chúng cùng kiểu với nhau.
(Nếu không quá nhiều biến ...)

Ví dụ:


{Trong 1 dòng}

USES CRT;
TYPE TSTRING64 = String [64];
VAR vX :Byte;

{Trong nhiều dòng}
USES
CRT,
DOS,
GRAPH;
TYPE
TSTRING64 = String [64];
TSTRING32 = String [32];
VAR
vX :Byte;
vY :Byte;
vZ :Byte;
vS :String [100];


5. Ở đầu chương trình chính/chương trình con: nên có chú thích về: chức năng của nó, các thư viện/các chương trình hay các biến dùng bên ngoài CT, các lưu ý nếu có ...
Khi cần thiết thì chú thích cho cả code.
Một chương trình hoàn chỉnh (dịch được/chạy được) có thể chỉ bao gồm BEGIN END không cần từ khóa nào khác; trước từ khóa END không nhất thiết phải có dấu ";" nhưng nên dùng báo đầy đủ.

6. Các hàm nào được gọi từ 1 UNIT ngoài (Khai báo trong phần USES <Tên các UNIT>)
thì nên đưa cả tên của UNIT đó vào bên cạnh tên hàm đó, bởi các hàm trong các thư viện có thể có tên giống nhau (giống/khác tham số, sửa đổi/bổ sung chức năng..) ==> sửa lỗi; sửa đổi nâng cấp thư viện, tránh nhiều tên cho 1 hàm ..
Ví dụ: Trong Graph .TPU có thủ tục InitGraph khởi động chế độ đồ họa; có ABC .TPU cũng có thủ tục khởi động chế độ đồ họa như InitGraph của Graph .TPU nhưng mạnh hơn; Nhưng thay vì đổi tên để tránh trùng tên như InitGraph1, MyInitGraph... nhiều phức tạp, thì ta vẫn lấy tên là InitGraph thêm tên UNIT đó vào trước (và bây giờ luôn biết InitGraph là thủ tục khởi động chế độ đồ họa); Khi cần dùng hàm/thủ tục trong trường hợp nào của thì dùng unit đó.
- Graph . InitGraph .....
- ABC . InitGraph .....
...

7. Chỉnh TAB:
- Nếu soạn code trong IDE của BP/TP, vào Option/Envỉonment/Editor chọn TAb Size = 4;
- Trong Notepad++:
  + Vào menu: Setting/Preferences/
  + Tìm Tab: Language Menu /Tab Settings
  + Chọn Tab Size = 4; và check vào ô Replace by Space.

ada95
12-11-2014, 13:56
Cài đạt BP7 FULL từ đầu (gồm khoảng ~105file ~14MB)
Sau khi cài máy thì có ~780file ~26MB (lúc này copy đâu cũng mất chút thời gian).
Nếu cần gọn nhẹ, nhanh chóng, dễ dàng mang đi đây đó, các bạn chỉ cần chép các file sau là đủ cho trình biên dịch hoạt động:

=10 FILE với dung lượng chỉ ~1,2MB:

1. BPW EXE (IDE)
2. BWCC DLL
3. PBROWSER DLL
4. TCOLORCC DLL

5. TURBO TPL (Thư viện chuẩn)
6. TPW TPL (Nếu không lập trình với Win thì có thể không cần chép)
7. TPP TPL (Nếu không lập trình chế độ bảo vệ thì có thể không cần chép)

8. bpw psm (03 file cấu hình)
9. bpw cfg
10. bpw dsk


**Trong lần khởi động đầu tiên, vào menu COMPILE chỉnh TARGET là REAL.
Sau khi thoát Chương trình sẽ hỏi nơi lưu cấu hình mới, ta chọn nơi lưu (chỉ 01 lần đầu, sau này BP không hỏi nữa)

ada95
12-11-2014, 14:20
Nếu dùng pascal trong windows, các bạn nên sử dụng trình soạn thảo NOTEPAD++

Đây là một chương trình rất hay:

- Soạn thảo dễ dàng như trong WORD.

- Hỗ trợ Highlight mã, căn lề, chú thích...

- Có gợi ý và hoàn thành hàm, từ khóa mỗi khi gõ lệnh:
+ Vào menu Setting ->Preferences->Backup/Auto-Completion
+ Đánh dấu 3 ô:
X Enable Auto-Completion ...
X Function Completion
X Function parameters hint ...

- Hỗ trợ xuất sang định dạng htm v.v ...
+ Menu Plugins -> nppExport ...

- Đặc biệt: Khi vào menu ENCODING và đánh dấu chọn vào mục Encode in UTF-8 without BOM, và lưu lại file, thì ta có thể ghi chú thích được bằng TIẾNG VIỆT, hoàn toàn không gây lỗi khi biên dịch trpng TPC, BPC, BPW

(Để mặc định: Vào menu Setting ->Preferences->New Doccument->UTF-8 without BOM->Apply ..)

* Sau khi soạn xong, mở BP7 lên, kéo thả file vào và dịch ...

ada95
12-11-2014, 14:30
Khi cần gọn nhẹ hơn nữa, thì chỉ cần file TPC EXE với TURBO TPL.
(Đồ họa thì thêm GRAPH TPU và EGAVGA OBJ)

Soạn lệnh trong notepad++, sau đó vào Dos: tpc /B <FILE> .PAS

ada95
14-11-2014, 11:50
Thư viện (Library) liên kết động trong pascal chương trình cơ bản giống Unit;
Khác nhau ở trình bày một số điểm chính (từ khóa chữ hoa/thường đều được):
- Từ UNIT ở đầu thay bằng LIBRARY; (Ten thu vien van trung ten file luu tren dia}
- Không có IMPLEMENTATION;
- Sau tên mỗi Chương trình con để gọi từ ngoài có thêm từ khóa EXPORT ;
- Có phần khai báo EXPORTS, đây là phần ta đánh chỉ số INDEX cho mỗi function/procedure có trong thư viện, đề từ đó gọi từ các Chương trình ngoài khác.

VÍ DỤ:


LIBRARY DDTH;

{1. PHẦN KHAI BÁOO KIỂU, HẰNG, BIẾN DÙNG CHUNG TRONG THƯ VIỆN, NẾU CÓ}
{
TYPE ....
CONST ....
VAR ....
}

{2. PHẦN CỤ THỂ CÁC CHƯƠNG TRÌNH CON} {thư viện này có 2 hàm:}
function fileExist (filename :string) :boolean; EXPORT;
var vfile :file;
begin
{$I-}
assign (vfile, filename);
reset (vfile);
close (vfile);
{$I+}
fileExist := (IOResult=0) and (filename<>'');
end;
{-------------------}
function sum (a, b :byte) :integer; EXPORT;
begin
sum := a+b;
end;

{3. PHẦN ĐÁNH CHỈ SỐ CHO CÁC CHƯƠNG TRÌNH CON CÓ TRONG THƯ VIỆN NÀY}
EXPORTS
fileExist INDEX 1,
sum INDEX 2;

{4. MAIN}
BEGIN
{Khởi tạo, nếu có}
END.

ada95
14-11-2014, 12:24
Cách sử dụng thư viện DDTH trên như sau:
- Khai báo các hàm ta dùng có trong thư viện đó;
- Thêm theo sau mỗi hàm là FAR; EXTERNAL 'DDTH' INDEX ***;
--


PROGRAM TESTDLL;
USES WinCRT;

{1. PHẦN KHAI BÁO CÁC HẰNG, BIẾN, KIỂU TRONG CHƯƠNG TRÌNH}
{
TYPE ....
CONST ....
VAR ....
}

{2. PHẦN KHAI BÁO CÁC HÀM/THỦ TỤC TRONG THƯ VIỆN}
{$F+}

function fileExist (filename :string) :boolean; FAR; EXTERNAL 'DDTH' INDEX 1;

function Sum (a, b :byte) :integer;FAR; EXTERNAL 'DDTH' INDEX 2;

{$F-}

{3. CÁC CHƯƠNG TRÌNH CON SỬ DỤNG THƯ VIỆN}
{Nếu có}
{4. CHƯƠNG TRÌNH CHÍNH}
BEGIN
InitWinCRT;

GotoXY (2, 5);
Writeln ('tong cua 5 va 7 la :', Sum (5,7));
Readln; {repeat until KeyPressed;}

if fileExist ('ddth---pas') then Writeln ('file ddth---pas ton tai tren dia')
else ('file ddth---pas khong ton tai tren dia');
Readln;

DoneWinCRT;
END.


**Yêu cầu có thư viện WinCrt TPU.
** Các đường dẫn, tên file, các bạn sửa lại cho đúng (do post <50).
--

ada95
17-11-2014, 13:07
Hàm (function) khác thủ tục (procedure) ở chỗ tuy cũng là chương trình con nhưng kết thúc hàm có trả lại một giá trị thông qua tên hàm của nó.

Pascal có 1 điều thú vị là cho phép sử dụng hàm như một thủ tục.
Đó là ta có thể gọi hàm như thủ tục, trong đó nó tính toán, hoặc làm điều gì đó như thủ tục; Nhưng phải trả về cho hàm 1 giá trí cuối cùng nào đó.

Ví dụ:


USES Crt, Graph;
{....
....}

{$L EGAVGA} procedure EGAVGABGI; external;
function InitGraphEGAVGA :boolean ;
var
GraphDriver :Integer;
GraphMode :Integer;
begin
GraphDriver := Detect;
RegisterBGIDriver (addr(EGAVGABGI)); {=RegisterBGIDriver(<at>EGAVGABGI};
InitGraph (GraphDriver, GraphMode,'');
InitGraphEGAVGA :=(GraphResult = 0);
end;


**Tạo EVAVGA_OBJ từ EVAVGA_BGI bằng lệnh dos:
BINOBJ EVAVGA_BGI EVAVGA EGAVGABGI


Chương trình con InitGraphEGAVGA khởi động chế độ đồ họa,
và trả về kết quả là InitGraphEGAVGA := (GraphResult = 0).

Thì trong chương trình chính, sử dụng cả 2 cách sau đều được:

Cách 1: Dùng như 1 FUNCTION bình thường, Khi cần kiểm tra:


BEGIN
if not InitGraphEGAVGA then;
begin
WriteLn ('Co loi trong khoi dong do hoa');
Halt (1);
end
else
begin
SetColor (BLUE);
MoveTo (10, 10);
LineTo (50, 50);
..........
..........
CloseGraph;
end;
END.


Cách 2: Dùng như 1 PROCEDURE; Không kiểm tra qua tên hàm


BEGIN
InitGraphEGAVGA;
...........
...........
CloseGraph;
END.



**Như vậy ta có thể khai báo hoàn toàn các chương trình con là function.
Kể cả các thủ tục nhập xuất dữ liệu, thông báo ... miễn là trả về cho nó 1 kết quả trong tên hàm.
**Tuy nhiên: Cẩn trọng nếu sử dụng.

ada95
19-11-2014, 16:32
- Hạn chế sử dụng biến toàn cục; Biến toàn cục chỉ nên được sử dụng trong thân của chương trình chính: truyền tham số cho các CTC tính toán và nhận kết quả (function), hoặc để CTC thực hiện công việc nào đó (procedure). Và mọi sự thay đổi biến toàn cục thực hiện tại đây.

- Trong CTC: chỉ sử dụng biến cục bộ, hoặc biến được truyền trong tham số của nó, chỉ sử dụng hằng số và kiểu của chương trình chính. Không có lệnh nào của CTC sử dụng (một cách tường minh) biến toàn cục hay làm thay đổi biến toàn cục,
(Mà nếu phải thay đổi biến toàn cục thì phải thông qua tham số của CTC, mà việc này phải được thực hiện tại thân của Chương trình chính như trên).

- Các chương trình con không được sử dụng bất cứ biến nào ngoài biến trong tham số của nó.

- Việc nhập dữ liệu/thông số đầu vào; xử lý/tính toán; và việc xuất kết quả ra màn hình/file nên tách biệt và đưa vào các CTC khác nhau.

- Các biến trong CTC nếu không chỉ rõ kiểu, thì trình dịch ngầm hiểu đó lá biến kiểu con trỏ.
Ví dụ:

VAR
C; {=>lỗi, vì không khai báo kiểu}
procedure XYZ (var test); {OK!}
..............
..................
BEGIN
................
.....................
END.

ada95
24-11-2014, 13:13
Biến, Kiểu, Hằng toàn cục có thể khai báo ở bất cứ đâu trong chương trình, không nhất thiết phải ở đầu chương trình (Nhưng không thuộc thân chương trình chính), như:



{-------------------------------------------------------------}
PROGRAM TEST;
{Vị trí 1.--------------------Khai báo 1-----------------------------}

TYPE
TS4=String[4];
CONST
C1=1000;
VAR
vB :byte;

{-------------------Các chương trình con------------------}

procedure AAA ......;
procedure PPP ......;

{Vị trí 2.--------------------Khai báo 2--------------------}

VAR
HHHHH :byte;

function FFF......;
procedure WWW ......;
.................................;
....................................;

{Vị trí 3.--------------------Khai báo 3---------------------}
TYPE
TS8=String[8];
CONST
C2=2000;
VAR
vH :byte;

{--------------Thân chương trình chính--------------------}
BEGIN

{code}

END.


=> Có thể khai báo ở 3 vị trí khác nhau:
VT1: đầu chương trình, thông dụng.
VT2: giữa các chương trình con.
VT3: Ngay trước thân chương trình chính.
Nhưng dễ và chắc chắn kiểm soát được là ở vị trí 1 (các vị trí khác có thể khiến mất kiểm soát biến, tìm và sửa lỗi)

**Tuy nhiên, với chương trình dài, thì có thể khai báo Biến/Kiểu/Hằng ở VT3 để test chương trình; Xong thì đưa lên VT1-đầu chương trình.

ada95
24-11-2014, 15:30
Trong chế độ thực, Turbo Pascal giới hạn phân đoạn dữ liệu (data segment) 64KB=65536 Byte.
Mọi khai báo Biến, Kiểu, cấp bộ nhớ ... đều phải có kích thước <=64KB.
Nếu >64KB: gây lỗi, sẽ không thể biên dịch được.

Ví dụ:


TYPE
TB = array [0..66000] ò Byte; { => Lỗi}

VAR
vP :Pointer;

BEGIN
GetMem (vP, 65540); { => Lỗi}
............................;
.....................................;
FreeMem (vP, 65540); { => Lỗi}
END.


Vậy, làm thế nào để cấp biến nhớ lớn hơn 64KB ?
Trong DOS, có cách giải quyết như sau:

- Trong các ngắt (interrupt) của DOS (ngắt 21h) có:
...+ Hàm 48h: là cấp phát bộ nhớ RAM; --Như thủ tục GetMem;
...+ Hàm 49h: giải phóng bộ nhớ RAM; --Như thủ tục FreeMem;
...+ Hàm 4ah: thay đổi kích thước vùng nhớ.
...
Trong phần này ta chỉ quan tâm đến hàm 48h và 49h.

- Phần vùng nhớ cấp phát được lấy từ Bộ nhớ quy ước (?) (Conventional Memory: Là vùng bộ nhớ từ 0 KB đến 640KB trong DOS).

- Kích thước vùng nhớ yêu cầu cấp phát được tính theo paragraph (nghĩa là: đoạn, phần ???).
Mỗi paragraph = 16 byte.
Do đó: số paragraph cần cấp = Số Byte cần cấp chia cho 16.
Ví dụ: nếu cần cấp 64KB bộ nhớ thì phải yêu cầu cấp (64*1024)/16=4096paragraph.

- Mô tả các hàm:



{Cấp bộ nhớ}
function Alloc (vPara :Word) :Word; Assembler;
{Nếu thành công, Hàm này trả về giá trị kiểu Word,
là địa chỉ đoạn của vùng nhớ được cấp phát}
asm
mov ah,48h {Hàm 48h}
mov bx,vPara {Số paragraph bộ nhớ cần cấp phát}
inc bx
int 21h {Gọi ngắt 21h}
jnc <at>OK {Cờ Carry = 0: Thành công}
mov ax,$ffff {Cờ Carry = 1: Lỗi, thanh ghi ax lúc này chứa mã lỗi: }
{ax=7: Khối điều khiển bộ nhớ bị xóa}
{ax=8: Không đủ RAM; bx= kích thước bộ nhớ còn lại của RAM tính bằng paragraph}
<at>OK: {Cờ Carry = 0: Thành công}

end;
**Thay "<at>" bằng A CÒNG
{Giải phóng bộ nhớ}
procedure DeAlloc (vSegment :Word); Assembler;
asm
mov ah,49h {Hàm 49h}
mov es,vSegment {vSegment: Địa chỉ đoạn của vùng nhớ cần giải phóng}
int 21h {Gọi ngắt 21h}
end;
**Alloc: allocate/allocation: cấp phát

(code demo bổ sung sau)

ada95
24-11-2014, 17:24
Chương trình:



USES Dos;
VAR
FullPathProgramName :String;
Parameter :String;

procedure ExecProgram (FullPathProgramName, Parameter: String);
begin
SwapVectors;
Exec (FullPathProgramName, Parameter);
SwapVectors;
end;

{Chương trình chính}
BEGIN
WriteLn;
{------------}
{Xem địa chỉ card mạng}
FullPathProgramName:='C__WINDOWS__system32__getmac<dot>exe';
Parameter:='';
ExecProgram (FullPathProgramName, Parameter);
WriteLn;
{------------}
{Thực hiện 1 lệnh nội trú của MSDOS:}
SwapVectors;
Exec (GetEnv('ComSPEC'),'/c Dir /p'); {Lệnh Dir}
SwapVectors;
WriteLn;
{------------}
{Thực hiện 1 lệnh nội trú của MSDOS:}
SwapVectors;
Exec (GetEnv('ComSPEC'),'/c Ver'); {Lệnh Ver}
SwapVectors;
WriteLn;
{------------}
{Thực hiện 1 lệnh của MSDOS:}
SwapVectors;
Exec (GetEnv('ComSPEC'),'/c Dir__/l/s>dir<dot>txt'); {Lệnh Dir}
SwapVectors;
WriteLn;

{------------}
WriteLn('...back from Exec');
if DosError <> 0 then { Error? }
WriteLn('Dos error #', DosError)
else
WriteLn('Exec successful. ', 'Child process exit code = ', Do***itCode);
WriteLn;
WriteLn ('ENTER TO EXIT');
readln;
WriteLn;

END.


** Không có tác dụng trong WIN7, kể cả khi dùng DOSBOX.
** Thay <dot> bằng dấu chấm.
** Thay dấu gạch dưới __ bằng ký tự "\"

ada95
01-12-2014, 10:57
Cách chuyển đổi cơ số (hệ đếm) qua lại, từ cơ số 2 đến cơ số 36:
(*
- Tại sao là 36 ? => vì: 36 = 10 số 0..9 và 26 chữ cái A..Z;
- Không giới hạn cơ số là bao nhiêu, lớn hơn nữa cũng được nhưng bạn phải có đủ ký tự để biểu diễn số đó;
- Mà 36 có lẽ cũng là quá đủ rồi!?..
*)

1. Một số có giá trị nào thì dù biểu diễn ở cơ số nào thì cũng không làm thay đổi giá trị của nó.
Ví dụ: Các số sau là như nhau:
125 (hệ 10) = 3H (hệ 36) = 7D (hệ 16) = 01111101 (hệ 2) = ...

2. Cách thức chuyển đổi số từ hệ này sang hệ khác đều giống nhau:
- Hệ 2 (nhị phân) có 2 ký số: 0, 1
- Hệ 8 (bát phân) có 8 ký số" 0,1,2,3,4,5,6,7
- Hệ 10 (thập phân) có 10 ký số: 0,1,2,3,4,5,6,7,8,9
- Hệ 16 (thập lục phân) có 16 ký số: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
...............
.....................
- Hệ 36 (Tam thập lục phân): 36 ký số: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
.........
.............

* Cách chuyển đổi:

Lấy số bị chia (số cần chuyển) chia cho số chia (=s=là hệ cần chuyển sang),
được số nguyên d0, dư m0,
+ lấy d0 chia tiếp cho s được d1, dư m1
+ lấy d1 chia tiếp cho s được d2, dư m2
+ lấy d2 chia tiếp cho s được d3, dư m3
+ .........
..................
+ chia đến khi nào d=0 thì dừng

=> Đến đây: lấy các số dư hợp lại: m(n)...m100,m99,...m4,m3,m2,m1,m0
chính là kết quả của số ở hệ mới.


* Ví dụ chuyển số ở Hệ 10-thập phân qua các hệ khác:

Chuyển số 45 (Hệ 10):

- Qua nhị phân (Hệ 2):


45 chia 2 = 22 dư 1
22 chia 2 = 11 dư 0
11 chia 2 = 5 dư 1
5 chia 2 = 2 dư 1
2 chia 2 = 1 dư 0
1 chia 2 = 0 dư 1 => d=0: Dừng!

=> Tổng hợp các số dư (từ dưới lên): 1 0 1 1 0 1
Vậy: 45 (Hệ 10) = 101101 (Hệ 2)


- Qua thập lục phân (Hệ 16):


45 chia 16 = 2 dư 13 = D (vì 13 tương ứng ký số D)
2 chia 16 = 0 dư 2 => d=0: Dừng!

=> Tổng hợp các số dư (từ dưới lên): 2 D
Vậy: 45 (Hệ 10) = 2D (Hệ 16)


- Qua hệ 36:


45 chia 36 = 1 dư 9
1 chia 36 = 0 dư 1 => d=0: Dừng!

=> Tổng hợp các số dư (từ dưới lên): 1 9
Vậy: 45 (Hệ 10) = 19 (Hệ 36)


- Qua các hệ khác: => tương tự như trên.

* Chuyển số qua hệ thập phân (Hệ 10):
- Ký hiệu hệ là s
- Số biểu diễn ở hệ s là: ... x7x6x5x4x3x2x1x0
- Thì giá trị ở hệ thập phân là:
= .. x7*s^7 + x6*s^6 + x5*s^5 + x4*s^4 + x3*s63 + x2*s^2 + x1*s^1 + x0*s^0
(Với số mũ chính là vị trí của từng ký số trong số đó).

Ta lấy luôn số liệu ở ví dụ trên:


- 101101 (Hệ 2): = 1*2^5 + 0*2^4 + 1*2^3 + 1*2^2 + 0*2^1 + 1*2^0 =
= 1*32 + 0*16 + 1*8 + 1*4 + 0*2 + 1*1 =
= 32 + 0 + 8 + 4 + 0 + 1 = 45 (Hệ thập phân).

- 2D (Hệ 16): = 2*16^1 + D*16^0 = 2*16 + 13*1 = 32 + 13 = 45 (Hệ thập phân).


- Các số hệ khác chuyển qua hệ thập phân cũng tương tự.

ada95
01-12-2014, 11:46
Có nhiều hàm chuyển đổi qua lại theo nhiều cơ số khác nhau:
- Từ hệ đếm cơ số 10 sang hệ 2;
- Từ hệ 10 sang hệ 16;
- Từ hệ 16 sang hệ 2;
- v.v.....
=> Như vậy, nếu chuyển đổi số từ cơ số này qua cơ số khác mà phải viết 1 hàm riêng thì bất tiện quá1

Để đơn giản cho việc chuyển đổi cơ số, ta thống nhất lấy Hệ thập phân là hệ chuẩn để tính toán, cũng như làm trung gian để chuyển đổi.

Sau đây là 2 hàm chuyển đổi cơ số dùng trong PASCAL (TP7, BP7, BPW7):
(Nguồn: webswag)

- function Base10toBaseS (Num_Base10 :LongInt; New_Base :Byte) :String;
(Chuyển đổi số hệ thập phân qua số ở hệ cơ số S)

- function BaseStoBase10 (Text :String; Base :Byte) :LongInt;
(Chuyển đổi số ở hệ cơ số S qua số hệ thập phân)

(*

**Chú ý:
- Hai hàm chỉ chuyển đổi các SỐ NGUYÊN KHÔNG ÂM (>=0);
- Sử dụng biến (số) kiểu LongInt, hiển thị dưới 2 dạng: LongInt/String;
- LongInt: là số nguyên 32bit có dấu, giá trị: -2147483648..2147483647;
- Nên khi chuyển đổi ở Cơ số nào thì Số cũng phải >= 0 và <= 2.147.483.647;
- Muốn dùng số lớn hơn, hay với số âm: tùy ý chỉnh sửa ...;
- BaseChars: Chữ Hoa hay chữ thường nếu thấy nào dễ nhìn hơn.

**Cách Sử dụng hàm:
1. function BaseStoBase10 (Text :String; Base :Byte) :LongInt;
- Chuyển 1 số (<= 2.147.483.647) thể hiện dưới dạng String,
- ở cơ số Base: (=10=Thập phân, =16=Thập lục phân, =2=Nhị phân, ..V.V.),
- Sang số ở Hệ 10 - Hệ thập phân, kiểu LongInt;

2. function Base10toBaseS (Num_Base10 :LongInt; New_Base :Byte) :String;
- Chuyển 1 số hệ thập phân/Num_Base10 (<= 2.147.483.647),
- Sang số ở Cơ số khác: New_Base,
- Kết quả thể hiện dưới dạng String;

3. Chuyển đổi giữa các hệ khác: dùng hệ 10 làm trung gian:

- Ví dụ: chuyển số 45FFD hệ 16 qua hệ 2 như sau:
+ Chuyển 45FFD he 16 qua hệ 10: X := BaseStoBase10 ('45FFD', 16);
+ Sau đó mới chuyển qua hệ 2: Y := Base10toBaseS (X, 2);
+ Hoặc như thế này: Z := Base10toBaseS (BaseStoBase10 ('45FFD', 16), 2);

*)


function BaseStoBase10 (Text :String; Base :Byte) :LongInt;



function BaseStoBase10 (Text :String; Base :Byte) :LongInt;
var
center :Byte;
leng :Byte;
vL :LongInt;
vdigit :Boolean;
vb :Boolean;
vA :Char;
vZ :Char;
vCHAR :Char;
begin
vL := 0;
vA := Char(65);
vZ := Char(64 + Base - 10);
vb := false;
vdigit := false;
leng := Length (Text);
center := 1;
while center <= leng do
begin
vCHAR := UpCase (Text [center]);
case vCHAR of
'-' : if vdigit then center := leng
else vb := true;
'0'..'9': if Byte (vCHAR) - 48 < Base then
begin
vL := Base*vL + Byte(vCHAR) - 48;
vdigit := true;
end
else center := leng;
' ': if vdigit then center := leng;
else {Case}
begin
if (vCHAR >= vA) and (vCHAR <= vZ) then
vL := Base*vL + Byte(vCHAR) - 65 + 10
else
center := leng;
end;
end; {Case}
center := center + 1;
end;
if vb then vL := -vL;
BaseStoBase10 := vL;
end; {BaseStoBase10}


function Base10toBaseS (Num_Base10 :LongInt; New_Base :Byte) :String;



function Base10toBaseS (Num_Base10 :LongInt; New_Base :Byte) :String;
const
BaseChars :Array [0..36] of Char = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; {CHỮ HOA}
{BaseChars :Array [0..36] of Char = '0123456789abcdefghijklmnopqrstuvwxyz';} {chữ thường}
var
Text :String;
begin
Text := '';
repeat
Text := BaseChars [Num_Base10 mod New_Base] + Text;
Num_Base10 := Num_Base10 div New_Base;
until Num_Base10 = 0;
Base10toBaseS := Text;
end; {Base10toBaseS}


Ví dụ:




{Chương trình chính}
BEGIN
Writeln ('So 2147483647 he 10 qua he 36: ', Base10toBaseS(2147483647, 36));

Writeln ('So ZIK0ZJ he 36 qua he 10: ',BaseStoBase10 ('ZIK0ZJ', 36));

Writeln ('So 7FFFFFFF he 16 qua he 10: ', BaseStoBase10 ('7FFFFFFF', 16));

Writeln ('So 125 he 10 qua he 36: ', Base10toBaseS(125, 36));

Writeln ('So 125 he 10 qua he 16: ', Base10toBaseS(125, 16));

Writeln ('So 125 he 10 qua he 2: ', Base10toBaseS(125, 2));

Writeln ('So 45FFD he 16 qua he 2: ', Base10toBaseS (BaseStoBase10 ('45FFD', 16),2));

ReadLn;
END.

**Kỳ lạ: ban đầu để Base10toBase X: để chỉ cơ số X, thế mà ra Base10toBa*** ???, máy thật tinh tế và thông minh quá☻

ada95
11-12-2014, 16:19
Gồm 1 số hàm sau:

function ShiftPressed:Boolean; {Phím SHIFT phải và SHIFT trái}
function RightShiftPressed:Boolean; {Phím SHIFT phải}
function LeftShiftPressed:Boolean; {Phím SHIFT trái}
function CtrlPressed:Boolean; {Phím Control}
function AltPressed:Boolean; {Phím Alt}

function ScrollLockOn:Boolean; {Phím ScrollLock}
function NumLockOn: Boolean; {Phím NumLock}
function CapsLockOn: Boolean; {Phím CapsLock}
function InsertOn:Boolean; {Phím Insert}

- Hàm trả lại kết quả là TRUE khi các phím Shift/Ctr/Alt được nhấn;
Hoặc khi trạng thái các phím ScrollLockOn/NumLockOn/CapsLockOn được bật (đèn Sáng).

{** Đối với các phím ScrollLockOn/NumLockOn/CapsLockOn: có thể ứng dụng để thiết lập cấu hình trong chương trình (VD: tốc độ, số lượng, độ trễ, giá trị ...); tổ hợp trạng thái đèn của 3 phím này là 2^3= 8 cấu hình khác nhau).

Chi tiết các hàm:




{_________________________________________________ ______________}
function ShiftPressed:Boolean; assembler;{Phím SHIFT phải và SHIFT trái}
asm
mov ah,02h
int 16h
mov dl,al
and al,1 {1}
cmp al,1
je A_A1
and dl,2 {2}
cmp dl,2
je A_A1
xor ax,ax
jmp A_A2
A_A1:
mov ax,1
A_A2:
end;
{_________________________________________________ ______________}
function RightShiftPressed:Boolean; assembler;{Phím SHIFT phải}
asm
mov ah,02h
int 16h
and al,1 {1}
cmp al,1
je A_A1
xor ax,ax
jmp A_A2
A_A1:
mov ax,1
A_A2:
end;
{_________________________________________________ ______________}
function LeftShiftPressed:Boolean; assembler;{Phím SHIFT trái}
asm
mov ah,02h
int 16h
and al,2 {2}
cmp al,2
je A_A1
xor ax,ax
jmp A_A2
A_A1:
mov ax,1
A_A2:
end;
{_________________________________________________ ______________}
function CtrlPressed:Boolean; assembler;{Phím Control}
asm
mov ah,02h
int 16h
and al,4 {4}
cmp al,4
je A_A1
xor ax,ax
jmp A_A2
A_A1:
mov ax,1
A_A2:
end;
{_________________________________________________ ______________}
function AltPressed:Boolean; assembler;{Phím Alt}
asm
mov ah,02h
int 16h
and al,8 {8}
cmp al,8
je A_A1
xor ax,ax
jmp A_A2
A_A1:
mov ax,1
A_A2:
end;
{_________________________________________________ ______________}
function ScrollLockOn:Boolean; assembler;{Phím ScrollLock}
asm
mov ah,02h
int 16h
and al,16 {16}
cmp al,16
je A_A1
xor ax,ax
jmp A_A2
A_A1:
mov ax,1
A_A2:
end;
{_________________________________________________ ______________}
function NumLockOn:Boolean; assembler;{Phím NumLock}
asm
mov ah,02h
int 16h
and al,32 {32}
cmp al,32
je A_A1
xor ax,ax
jmp A_A2
A_A1:
mov ax,1
A_A2:
end;
{_________________________________________________ ______________}
function CapsLockOn:Boolean; assembler;{Phím CapsLock}
asm
mov ah,02h
int 16h
and al,64 {64}
cmp al,64
je A_A1
xor ax,ax
jmp A_A2
A_A1:
mov ax,1
A_A2:
end;
{_________________________________________________ ______________}
function InsertOn:Boolean; assembler;{Phím Insert}
asm
mov ah,02h
int 16h
and al,128 {128}
cmp al,128
je A_A1
xor ax,ax
jmp A_A2
A_A1:
mov ax,1
A_A2:
end;
{_________________________________________________ ______________}


{
Lưu ý:
Thay chữ "A_A" bằng 2 ký tự A-CÒNG đứng liền nhau như thế này "aa",
vào bất kỳ CT soạn thảo nào: sử dụng chức năng tìm kiếm và thay thế nhanh chóng
}

ntn5464
15-12-2014, 21:05
SỐ NGUYÊN TỐ GHÉP:
Xét dãy A các số nguyên tố 2, 3, 5, 7, 11, 13, 17, 19,...
và dãy B gồm các số thu được từ dãy A bằng cách ghép hai số liên tiếp trong A: 23, 57, 1113, 1719, ...
Trong dãy B có những phần tử là số nguyên tố. Chẳng hạn 23, 3137, 8389, 157163...
Các số nguyên tố trong dãy B gọi là số nguyên tố ghép.
Yêu cầu: Cho trước số nguyên dương K ≤ 500, hãy tìm số nguyên tố ghép thứ K.
-->>>> Ai cho em code đi.... Có quà đấy