Như đã hứa tôi viết vội một code để test cho trường hợp ~ 65000 dòng không trùng nhau từng đôi một. Như Hải nói thì code không dùng DIC mà Hải đưa ra chạy mất 180 s.
Mà Hải lại kiên nhẫn nên nhờ Hải test hộ - vì tôi chỉ test vài lần xem code chạy có lỗi hay không mà thôi. Hải hãy test và thông báo kết quả. Đừng sợ, tôi không "ác" như "tay" Tuấn đâu.
Như đã hứa tôi viết vội một code để test cho trường hợp ~ 65000 dòng không trùng nhau từng đôi một. Như Hải nói thì code không dùng DIC mà Hải đưa ra chạy mất 180 s.
Tôi thử cải tiến để giảm thời gian.
Không dám nhờ Tuấn test hộ vì
Mà Hải lại kiên nhẫn nên nhờ Hải test hộ - vì tôi chỉ test vài lần xem code chạy có lỗi hay không mà thôi. Hải hãy test và thông báo kết quả. Đừng sợ, tôi không "ác" như "tay" Tuấn đâu.
Tôi đã làm xong và test thử. Kết quả "khủng" quá nên nhờ mọi người test kỹ hộ.
Về unique max (min chắc là tương tự) thì:
1. Nếu dữ liệu vào (cột Unique) chưa sắp xếp, vd. từ "Nguyễn 1" tới "Nguyễn 64800" thì tốc độ trung bình.
2. Nếu dữ liệu được sắp xếp tăng dần - các bạn sort cột B tăng dần - thì tốc độ nhanh nhất
3. Nếu dữ liệu được sắp xếp giảm dần - các bạn sort cột B giảm dần - thì tốc độ chậm nhất.
Thời gian gâp 2 lần so với sắp xếp tăng dần.
----------------
Nếu điểm 3 là đúng thì dễ thôi. Nếu ta biết chắc chắn là dữ liệu được sắp xếp giảm dần mà thứ tự trả về không cần theo thứ tự như dữ liệu đầu vào thì ta gọi ADD cho các phần tử từ dòng cuối tới dòng đầu. Trong mọi trường hợp khác ta gọi ADD cho các phần tử từ dòng đầu tới dòng cuối
Cụ thể thời gian là bao nhiêu thì các bạn thông báo nhé.[/QUOTE
của em nó báo thế này 64bit đc nghĩ phép,
gõ chữ việt nó cu nhay ve dau dong ko a, kho chiu qua
Em nghĩ anh nên mở 1 topic mới để nói về những gì anh viết
- Thứ nhất: Nó quá cao cấp, để ở đây có phải phí quá không?
- Thứ hai: Chủ topic chắc muốn càng có nhiều thành viên mới vào đây tham gia và.. "múa" (mà thấy mấy bài kiểu như của anh chắc cụp đuôi luôn)
----------------
Những kiến thức tương tự như trong file của anh phải nói là hiếm khi gặp nên nếu có thể được ta nên cho nó vào 1 chổ thật trang trọng. Anh nghĩ sao?
Em nghĩ anh nên mở 1 topic mới để nói về những gì anh viết
- Thứ nhất: Nó quá cao cấp, để ở đây có phải phí quá không?
- Thứ hai: Chủ topic chắc muốn càng có nhiều thành viên mới vào đây tham gia và.. "múa" (mà thấy mấy bài kiểu như của anh chắc cụp đuôi luôn)
----------------
Những kiến thức tương tự như trong file của anh phải nói là hiếm khi gặp nên nếu có thể được ta nên cho nó vào 1 chổ thật trang trọng. Anh nghĩ sao?
Em nghĩ anh nên mở 1 topic mới để nói về những gì anh viết
- Thứ nhất: Nó quá cao cấp, để ở đây có phải phí quá không?
- Thứ hai: Chủ topic chắc muốn càng có nhiều thành viên mới vào đây tham gia và.. "múa" (mà thấy mấy bài kiểu như của anh chắc cụp đuôi luôn)
----------------
Những kiến thức tương tự như trong file của anh phải nói là hiếm khi gặp nên nếu có thể được ta nên cho nó vào 1 chổ thật trang trọng. Anh nghĩ sao?
Chài ai, trước là "phó thường dân", giờ là MOD òy! Thầy mà thấy những bài hay, có tính học thuật cao, thì Thầy cứ thế mà mở topic chuyên đề mới và dời bài vào đó thôi, đâu có xóa đâu mà ngại chứ Thầy!
Chài ai, trước là "phó thường dân", giờ là MOD òy! Thầy mà thấy những bài hay, có tính học thuật cao, thì Thầy cứ thế mà mở topic chuyên đề mới và dời bài vào đó thôi, đâu có xóa đâu mà ngại chứ Thầy!
Đâu có được. Vấn đề là phải được sự đồng ý của tác giả, vì đâu phải chỉ viết một bài rồi thôi
(tại vì thấy trong code có mấy cái Property Get gì gì đó, nhìn đơn giản nhưng thật sự chưa thông lắm)
Đâu có được. Vấn đề là phải được sự đồng ý của tác giả, vì đâu phải chỉ viết một bài rồi thôi
(tại vì thấy trong code có mấy cái Property Get gì gì đó, nhìn đơn giản nhưng thật sự chưa thông lắm)
Trước tiên tôi muốn nói 1 điều: có nhiều "trường phái" mà tôi là tín đồ của trường phái X.
Trường phái X cho rằng đối tượng - object phải hermetic. Mọi truy cập tới dữ liệu - các trường trong object đều phải thông qua thuộc tính.
Nhưng có người trong class module Class1 lại viết:
Mã:
Public data as Long
Rồi trong Module1:
Mã:
Dim a as New Class1
...
a.data = 5 <--- A
hoặc b = a.data + 5 <--- B
Như thế data như là biến Public
---------
Mỗi object có thể có nhiều trường dữ liệu. Một số dữ liệu có thể cho phép user truy cập, một số khác chỉ dùng trong lòng object mà thôi. Ví dụ như ArrIndex trong code của tôi chỉ dùng "nội bộ" trong object chứ không cung cấp cho user. Trường phái X cho rằng object phải kín và mọi truy cập tới dữ liệu phải thông qua thuộc tính. Nếu thuộc tính là read thì phải có Property Get. Nếu thuộc tính là write nhưng không là object thì phải có Property Let, còn nếu thuộc tính là Object thì thay vì Property Let phải là Property Set.
Muốn viết được A ở trên thì thuộc tính data phải là write (ta xét data như là thuộc tính - tôi viết ở dưới), còn nếu muốn viết B thì thuộc tính data phải là read. Muốn viết A và B thì thuộc tính data phải là read-write, tức có cả Property Get và Property Let. Tuấn giỏi tiếng Anh thì đọc Property Get và Property Let phải hiểu chứ.
Nếu chỉ có vd. Property Get thì thuộc tính là read-only. Lúc đó thì giá trị của trường data (chính xác hơn là trường ldata) sẽ được thiết lập bởi code trong class. Ví dụ thuộc tính count, keys, values trong code của tôi là read-only, giá trị của các dữ liệu đó do code trong class thiết lập chứ user không thiết lập được (read-only do không có Property Let. Tất nhiên đây là chủ ý vì những dữ liệu này phải do code trong class thiết lập chứ sao lại do user thiết lập được). Thông qua các thuộc tính này ta có thể truy cập tới những dữ liệu có trong object, cụ thể là truy cập tới giá trị được "cất giữ" trong các trường lCount, ArrKeys, ArrValues. Nhưng thuộc tính UniqueType thì lại do user thiết lập, vậy phải có Property Let để nó là write.
---------------
Vậy theo trường phái X thì là code phải viết như sau:
Mã:
Private ldata as Long
Public Property Get [COLOR=#ff0000]data[/COLOR]() As Long
data = ldata
End Property
Public Property Let [COLOR=#ff0000]data[/COLOR](ByVal Value As Long)
ldata = Value
End Property
Lúc đó thực hiện A có nghĩa là thực hiện "Public Property Let data" với Value = 5, tức ghi 5 vào ldata (ldata = Value)
Thực hiện a.data trong B chẳng qua là thực hiện Property Get, tức đọc ra giá trị của trường ldata.
ldata là trường trong object mà user ghi giá trị vào thông qua Property Let, và cũng từ trường đó user đọc ra giá trị thông qua Property Get. Tức write và read thông qua THUỘC TÍNH data.
data là tên thuộc tính, còn ldata là trường chứa dữ liệu. Trong th trên thì user truy cập tới trường dữ liệu ldata thông qua thuộc tính data. User không "nhìn" thấy được ldata (ở đây nhìn thấy nhưng nếu code nằm trong DLL thì sao?). user chỉ "nhìn" thấy thuộc tính data mà thôi.
Cũng như trong DIC ta có thuộc tính Count. user chỉ nhìn thấy thuộc tính Count chứ làm gì "nhìn" thấy trường "cất giữ" giá trị Count - nó là iCount, lCount, hay hichicCount? Ai mà biết được. Chỉ biết là có thể đọc giá trị của nó thông qua thuộc tính Count
data là tên thuộc tính, còn ldata là trường chứa dữ liệu. Trong th trên thì user truy cập tới trường dữ liệu ldata thông qua thuộc tính data. User không "nhìn" thấy được ldata (ở đây nhìn thấy nhưng nếu code nằm trong DLL thì sao?). user chỉ "nhìn" thấy thuộc tính data mà thôi.
Cũng như trong DIC ta có thuộc tính Count. user chỉ nhìn thấy thuộc tính Count chứ làm gì "nhìn" thấy trường "cất giữ" giá trị Count - nó là iCount, lCount, hay hichicCount? Ai mà biết được. Chỉ biết là có thể đọc giá trị của nó thông qua thuộc tính Count
Đấy đấy, vấn đề bắt đầu được "mở" rồi đây!
Em học lập trình chủ yếu thông qua các ví dụ, từ đó mà "ngộ" ra vấn đề
Trên mạng (thậm chí là trong Help cũng có), em đọc rất nhiều về mấy cái Property Let, Get, Set này. Tiếc là một số ví dụ quá đơn giản, đến mức xem thì hiểu mà chẳng biết mở rộng và phát triển nó thế nào... Một số ví dụ (hoặc 1 đoạn code hoàn chỉnh) lại quá phức tạp, đến mức khiến ta không biết đường đâu mà lần
Vậy nên cái em cần là 1 ví dụ ở tầm trung bình để vừa có thể hiểu lại mang tính áp dụng cao (thực tế)
Mấy "trò chơi" này cũng hơi trừu tượng: Hoặc sẽ hiểu thông vấn đề và áp dụng được ngay lập tức; hoặc sẽ chẳng bao giờ hiểu
Hic...
---------------------------
Đấy đấy, vấn đề bắt đầu được "mở" rồi đây!
Em học lập trình chủ yếu thông qua các ví dụ, từ đó mà "ngộ" ra vấn đề
Trên mạng (thậm chí là trong Help cũng có), em đọc rất nhiều về mấy cái Property Let, Get, Set này. Tiếc là một số ví dụ quá đơn giản, đến mức xem thì hiểu mà chẳng biết mở rộng và phát triển nó thế nào... Một số ví dụ (hoặc 1 đoạn code hoàn chỉnh) lại quá phức tạp, đến mức khiến ta không biết đường đâu mà lần
Vậy nên cái em cần là 1 ví dụ ở tầm trung bình để vừa có thể hiểu lại mang tính áp dụng cao (thực tế)
Mấy "trò chơi" này cũng hơi trừu tượng: Hoặc sẽ hiểu thông vấn đề và áp dụng được ngay lập tức; hoặc sẽ chẳng bao giờ hiểu
Hic...
---------------------------
Đừng nói là đọc tiếng Anh cho xa xôi! Anh viết bằng TIẾNG VIỆT có khi em đọc còn không hiểu nữa là...
Ẹc... Ẹc...
Đấy đấy, vấn đề bắt đầu được "mở" rồi đây!
Em học lập trình chủ yếu thông qua các ví dụ, từ đó mà "ngộ" ra vấn đề
Trên mạng (thậm chí là trong Help cũng có), em đọc rất nhiều về mấy cái Property Let, Get, Set này. Tiếc là một số ví dụ quá đơn giản, đến mức xem thì hiểu mà chẳng biết mở rộng và phát triển nó thế nào... Một số ví dụ (hoặc 1 đoạn code hoàn chỉnh) lại quá phức tạp, đến mức khiến ta không biết đường đâu mà lần
Vậy nên cái em cần là 1 ví dụ ở tầm trung bình để vừa có thể hiểu lại mang tính áp dụng cao (thực tế)
Mấy "trò chơi" này cũng hơi trừu tượng: Hoặc sẽ hiểu thông vấn đề và áp dụng được ngay lập tức; hoặc sẽ chẳng bao giờ hiểu
Hic...
Cái này dễ hiểu thôi
1. Ta xác định xem ta có những trường dữ liệu nào. Mọi trường ta khai báo là Private.
Đánh dấu những trường mà ta sẽ cho phép user truy cập vào thông qua các thuộc tính.
2. Để user có thể truy cập được vào các trường dữ liệu thì ta tạo ra mỗi thuộc tính ứng với mỗi
trường dữ liệu. Tên thuộc tính là tùy ý tuy nhiên nên đặt sao cho ngắn gọn mà dễ hiểu.
3. Viết các code Property. Nếu cho phép user đọc (read) thì phải cung cấp - viết Property Get. Nếu
cho phép ghi thì phải cung cấp Property Let hoặc Property Set.
Ví dụ ta lưu giữ một giá trị Long trong trường có tên là mInterval. Và cho phép user đọc và ghi. Vậy
ta phải tạo ra một thuộc tính. Ta chọn tên là Interval. Thế thì code có thể như sau:
Mã:
Private mInterval as Long
Property Get Interval() as Long
' procedure được thực hiện khi code của user đọc thuộc tính. Vậy ta cung cấp giá trị
' đang được lưu trong trường mInterval
[COLOR=#0000ff]Interval = mInterval[/COLOR]
End Property
Property Let Interval(Byval Value as Long)
' procedure được thực hiện khi code của user thay đổi giá trị của thuộc tính
' vậy ta thay đổi giá trị đang được lưu trong mInterval (để khi user cần đọc ra thì nó
' đúng là giá trị mà "anh ta" đã "đưa" vào)
[COLOR=#0000ff]mInterval = Value[/COLOR]
End Property
Tất nhiên code cho 2 procedure trên có thể phức tạp hơn. Ví dụ Interval phải là số không âm. Thế thì
trong Property Let ta phải kiểm tra giá trị của Value:
Mã:
Property Let Interval(Byval Value as Long)
If Value < 0 then
mInterval = 0
else
mInterval = Value
end if
End Property
Nhiều khi procedure còn phức tạp hơn. Ví dụ ta đang làm 1 class để tạo Timer (dùng SetTimer và
KillTimer) mà user bật, tắt Timer bằng cách thiết lập thuộc tính Enabled. Vậy thì việc thay đổi 1 thuộc
hiện nhiều SUB khác.
Ví dụ khi user thay đổi Interval thì Property Let Interval được gọi (debug là biết ngay mà). Trong code
của nó ta phải có: mInterval = Value (lưu giá trị vào trường mInterval). Nhưng trước khi làm việc đó
thì ta phải tắt Timer (mEnabled = FALSE, KillTimer), và sau đó ...
Nói chung code trong các Property là tùy từng trường hợp. Cái "khung tối thiểu" thì như trên tôi đã
đưa.
-------------------
Nhắc lại:
1. Xác định các trường dữ liệu mà ta sẽ cho phép user truy cập.
2. Với mỗi trường trong điểm 1 ta tạo 1 thuộc tính với tên thích hợp.
3. Viết các code Property Get, Let, Set. Nếu chỉ có Property Get thì thuộc tính là read-only, nếu chỉ
có Property Let thì user không đọc được thuộc tính.
-----------------
Nên nhớ là thuộc tính, hay nói chính xác hơn là trường lưu trữ giá trị của thuộc tính, không phải là
biến Public. Với biến Public thì user có thể đọc và thay đổi giá trị. Nhưng thuộc tính không nhất thiết
Private Sub UserForm_Initialize()
Dim Ctrl As Control, n As Long
Set lblOld = Nothing
For Each Ctrl In Me.Frame1.Controls
n = n + 1
ReDim Preserve lblObj(1 To n)
Set lblObj(n).lbl = Ctrl
Next
End Sub
Class1:
Mã:
Option Explicit
Public WithEvents lbl As MSForms.Label
Private Sub lbl_Click()
On Error Resume Next
lblOld.SpecialEffect = fmSpecialEffectRaised
lbl.SpecialEffect = fmSpecialEffectSunken
Set lblOld = lbl
End Sub
Một hôm ông tín đồ của trường phái X đọc được code và thốt lên: Trời ơi, sao lại làm thế! Mọi dữ liệu phải là Private, không có chuyện cho phép user tự do đọc, hoặc thay đổi được. Những dữ liệu nào cho phép truy cập thì tạo ra thuộc tính và bằng cách này cho phép user truy cập. Nhưng lúc này có thể chỉ cho 1 quyền đọc hoặc ghi thôi chứ không tùy tiện như trước được.
Và ông tín đồ tạo ra thuộc tính gọi là Label. Và user từ giờ trở đi không thể truy cập trực tiếp vào lbl để đọc và ghi được nữa. User chỉ truy cập gián tiếp vào lbl thông qua thuộc tính Label, và chỉ có thể thiết lập (write) mà thôi. User thiết lập thuộc tính Label trong UserForm_Initialize()
Mã:
Option Explicit
Dim lblObj() As New Class1
Private Sub UserForm_Initialize()
Dim Ctrl As Control, n As Long
Set lblOld = Nothing
For Each Ctrl In Me.Frame1.Controls
n = n + 1
ReDim Preserve lblObj(1 To n)
Set lblObj(n).[COLOR=#ff0000]Label[/COLOR] = Ctrl ' <-- A thiết lập thuộc tính Label
Next
End Sub
Mã:
Option Explicit
Private WithEvents lbl As MSForms.Label
Property Set Label(ctl As MSForms.Label)
Set lbl = ctl
End Property
Cám ơn Thầy Siwtom, nhờ bài này mà em hiểu thêm được nhiều, em mới tiếp cận với Class Module vài ngày nay, giờ gặp được bài viết này giống như trời hạn gặp mưa! Thầy rất tỉ mỉ trong việc trình bày và lời văn cũng rất mộc mạc, gần gũi và dễ hiểu.
Hay là Thầy tham gia trong Ban Quản trị diễn đàn đi nhỉ?