PDA

View Full Version : Xin chỉ giúp em cách hoàn chỉnh Unit này !



Samir Duran
25-04-2004, 06:04
Em đang dở dang một Unit tên là TTC_Equation , trng đó có xây dựng sẵn rất nhiều hàm và thủ tục thông dụng hay cần đến choo các chương trình bình thường . Nay em muốn tối ưu phần thủ tục vẽ hình học 2 chiều bằng Pascal ( i.e đường thẳng , đường cao , phân giác ... ) nhưng muốn nâng cấp mã theo hướng OOP (mục đích cuối của em là làm một chương trình ứng dụng vẽ và giúp giải hình học phẳng , bao gồm cả việc cho các đối tượng thay đổi vị trí và giá trị ), xin các anh chị giúp đỡ . XIn cảm ơn . Địa chỉ của em là thanhtong89@yahoo.com .

bete
25-04-2004, 06:33
Gửi Samir Dủan: tui chỉ xài WinZip => 0 biết làm sao đọc đựoc cái .rar của bạn ?

Huynh Phong
25-04-2004, 18:56
Tui có tham khảo sơ qua unit của bạn. Mạn phép nhé, thật lòng tui nhận thấy có nhiều chổ bạn dùng Var & cấu trúc không thích hợp. Ví dụ như:
{------------------------------------------------------------------------}
Procedure SuperTrim(var S : String) ;
Var t : integer ;
begin
for t := 1 to length(s) DO if ((S[t] = ' ') and (S[t+1] = ' ')) or ((S[t] = #9) and (S[t+1] = #9)) then
begin
delete(s,t,1);
t := t - 1 ;
end;
end;
{------------------------------------------------------------------------}
Trước hết, bạn không nên dùng t là Integer, bởi High(S) cao lắm là 1 byte (255), cho nên bạn dùng t:byte là đủ (integer chiếm 2byte còn byte chỉ chiếm 1byte).
Thứ đến, chắc chắn gì S sẽ không phải là 1 chuỗi rỗng ?. Vì thế bạn có thể thêm hàm if: If S<>'' then For t:=1 to Length(S) do...
Và nữa, t nằm trong vòng lặp for, bạn không nên tùy tiện biến đổi giá trị lặp for, có nghĩa là bạn không nên gán t := t-1 vì sẽ làm vòng for chạy lung tung, lộn xộn khó kiểm sóat, bạn hãy dùng 1 biến khác.
{------------------------------------------------------------------------}
Procedure trên có nhvụ xóa 1 khỏang trống trong 2 khỏang trống liên tiếp của 1 chuỗi, kể cả phím Tab, tôi mạn phép làm lại như sau:
Procedure SuperTrim( Var S:String);
Var b:boolean;
begin
b :=true;
While b do
begin if Pos(#32#32,S)<>0 then delete(s,pos(#32#32,S),1) else
if Pos(#09#09,S)<>0 then delete(s,pos(#09#09,S),1) else b:=Not b;
end;
end; { end pro }
{------------------------------------------------------------------------}
Bây giờ, bạn hãy chạy thử đoạn chương trình trên xem.

Samir Duran
25-04-2004, 19:43
Cảm ơn anh Huỳnh Phong về đoạn code , nhưng em thấy chương trình hình như vẫn chạy tốt mà ! ( mặc dù hơi tốn bộ nhớ và khó hiểu ) .
Dạ ! Em sẽ upload bản Zip của TTC_equation (coi bộ File nén kiểu Rar được nhiều người xài lắm mà , anh Bete ? )
Mong được mọi người "chỉ giáo" về phần đồ họa của em trong Unit (vì các thủ tục trên rất dễ làm , em chỉ gộp chung nó với phần Graph cho tiện thôi)
Xin cảm ơn !

bete
25-04-2004, 20:17
*) thân gửi Samir Duran: chưa đọc được file .rar của bạn, nhưng từ bài của Huynh Phong:

for t := 1 to length(s) DO if ((S[t] = ' ') and (S[t+1] = ' ')) or ((S[t] = #9) and (S[t+1] = #9)) then

1) giả sử s có chiều dài là 5, s tận cùng bằng 1 ký tự trống. Khi t=5 => s[t] = ' '
s[t+1]=s[6] 0 còn thuộc s (vì s chỉ có 5 ký tự) . Nếu s[6] ngẫu nhiên là ký tự trống => sẽ delete s[5] => đúng . Nhưng nếu s[6] ngẫu nhiên 0 là ký tự trống => sẽ 0 delete s[5] => đây có là ý bạn muốn ?

2) Tương tự như trên nếu s tận cùng là ký tự tab

3) vòng lặp sẽ là chậm khi bạn xài "for t := 1 to length(s) ....." (bạn tưởng tượng mỗi lần lặp lại thì chương trình phải tính lại length(s)) => bạn có thể thay là
"len := length(s); for t := 1 to len ...."

**) thân gửi Huynh Phong:

1) nếu s tận cùng với 1 (& chỉ 1 chứ 0 hơn) ký tự trống hoặc ký tự tab => mã của bạn sẽ 0 delete được ký tự cuối này (giống như chương trình gốc) => có phải là ý của bạn ?

2) mã của bạn sẽ chậm:

a) "if Pos(#32#32,S)<>0 then delete(s,pos(#32#32,S),1) ..."
==> bạn phải gọi hàm pos 2 lần

b) tương tự cho "if Pos(#09#09,S)<>0 then delete(s,pos(#09#09,S),1) ..."

c) giả sử bạn sửa lại là:

While b do
begin
p := Pos(#32#32,S);
if p<>0 then delete(s,p,1) else
begin p := Pos(#09#09,S); if p<>0 then delete(s,p,1) end
else b:=Not b;
end;

thì cũng vẫn còn chậm: bạn tưởng tượng s có 200 ký tự, s có 2 ký tự trống ở vị trí 50 & 51, và có 2 ký tự trống khác ở vị trí 100 & 101 => khi hàm pos được gọi lần thứ nhất sẽ quét từ ký tự 1 tới ký tự 51 & delete ký tự 51; hàm pos được gọi lần thứ hai sẽ quét từ ký tự 1 tới ký tự 101 & delete ký tự 101 => mỗi làn hàm pos được gọi thì nó lại phải quét từ ký tự 1 (đúng ra thì chỉ cần quét từ vị trí mới nhứt (của lần gọi ngay trước đó))

d) Hơn nữa mình tưởng tượng hàm delete: khi xóa ký tự ở vị trí k1 thì phải dồn các ký tự (k1+1) cho đến n (n là số ký tự có trong s) qua bên trái . Nếu mình gọi delete một lần nữa => xóa ký tự ở vị trí k2 thì phải dồn các ký tự (k2+1) cho đến n qua bên trái => các ký tự ký tự (k2+1) cho đến n (giả sử k2 > k1) bị dời qua trái 2 lần

Nhưng nếu chuỗi s hầu như 0 chứa nhiều ký tự trống & tab cho lắm thì chắc cũng 0 đáng để coi lại mấy chỗ trên !

(mong bạn đừng bực. Thú thiệt tui viết chương trình thì sai hoài à => cứ phải sửa lui sửa tới :))

(vài ý kiến thô thiển, nếu có gì sai sót mong các bạn chỉ giúp, xin cám ơn trước)

Huynh Phong
28-04-2004, 16:29
Thân gửi bete:
Đúng thiệt là dùng 2 lần Pos thì chương trình sẽ chậm hơn do máy phải dò chuỗi 2 lần, nhưng theo tớ, mình phải hết sức tiết kiệm bộ nhớ (vì là Unit mừ!), tớ không dzám sử dụng thêm 1 biến trung gian nữa, nghĩ thử xem, nếu 1 chương trình mà không cần dùng biến trung gian nhưng ..vẫn chạy tốt, thế thì tại sao mình phải hao tốn thêm bộ nhớ nhỉ. Càng tiết kiệm hơn nếu ta làm như thế này:
While True do
begin if Pos(#32#32,S)<>0 then delete(s,pos(#32#32,S),1) else
if Pos(#09#09,S)<>0 then delete(s,pos(#09#09,S),1) else Break;
end; Phải không bạn nhỉ, bỏ luôn Boolean, keo kiệt wá ! :emlaugh:
*Procedure trên không có nhiệm vụ delete 1 khỏang trống hoặc 1 Tab (làm theo nội dung Pro của Samir Duran) nên có kí tự trống ở cuối hay không thì ta không cần biết, nhiệm vụ của nó là hễ gặp 2(#32) hoặc 2(#09) thì delete 1(#32) hoặc delete 1(#09).
*Nói chi thì nói, trong thời đại tốc độ hiện nay, 1 ô nhớ không là bao, 1 max string cũng không là dài, do đó vấn đề thêm ô nhớ hay thời gian thi hành search 1 max string cũng không còn quan trọng, phải không bạn. Nhưng mình cũng nên chú ý đến thuật ngữ và cấu trúc hợp lý.