Ý tưởng Sort bằng Array

Liên hệ QC

Hoàng Trọng Nghĩa

Chuyên gia GPE
Thành viên BQT
Moderator
Tham gia
17/8/08
Bài viết
8,662
Được thích
16,718
Giới tính
Nam
Chắc chắn một điều rằng tôi chỉ mới "vọc" vấn đề mảng thời gian gần đây thôi nên không thể có những tư tưởng lớn như Sư phụ ptm0412, như Thầy ndu96081631, anh Sealand, v.v..., vì thế, khi thử nghiệm ý tưởng sắp xếp này cũng là "vung tay quá trán", tuy nhiên nếu có thể được phát triển bởi các Thầy, các Anh, hy vọng nó cũng là một đề tài được nhiều người bàn luận sôi nổi và có nhiều ý tưởng mới từ đề tài này:

PHP:
Sub LearnSortArr()
    Dim ArrOrg, sArray, sArr, ArrNew
    Dim I As Long, J As Long, N As Long
    
    ArrOrg = Range(Sheet1.[A2], Sheet1.[A65536].End(xlUp)).Value
    sArray = Range(Sheet1.[D2], Sheet1.[E65536].End(xlUp)).Value
    
    ReDim sArr(1 To UBound(ArrOrg), 1 To 2)
    
    N = 0
    For I = 1 To UBound(sArray)
        For J = 1 To UBound(ArrOrg)
            If sArray(I, 1) = ArrOrg(J, 1) Then
                N = N + 1
                sArr(J, 1) = ArrOrg(J, 1)
                sArr(J, 2) = sArray(I, 2)
                GoTo NextI
            End If
        Next
NextI:
    Next
    
    ReDim ArrNew(1 To N, 1 To 2)
    
    N = 0
    For I = 1 To UBound(sArr)
        If sArr(I, 1) <> "" Then
            N = N + 1
            ArrNew(N, 1) = sArr(I, 1)
            ArrNew(N, 2) = sArr(I, 2)
        End If
    Next
    
    Sheet1.[G2].Resize(N, 2).Value = ArrNew
End Sub
 

File đính kèm

  • SapXepArr.xls
    30 KB · Đọc: 46
Theo em nghĩ, chỉ cần mã hóa các chữ có dấu tiếng Việt (cả thường và hoa chỉ có 148 ký tự), phương thức Sort trong sheet sẽ làm việc với những phần còn lại, em lại nghĩ sort 2 chiều của Thầy cũng có phương thức sort, vậy thì không cần cả một thư viện ký tự làm chi? Chỉ cần mã hóa cột cần sort, còn những cột khác không cần thiết.

Cũng chẳng ai Sort cái cột có công thức (nếu có sort làm sao đây? còn duyệt luôn thì giá trị true, false cứ theo F trước T sau).
Nếu sort trên sheet thì sao gọi là Ý TƯỞNG SORT BẰNG ARRAY?
Mai nay bạn định sort trên ListBox bằng cách nào? Đừng nói là copy toàn bộ ra sheet, sort xong cho vô ListBox trở lại nha! Mà cứ cho là tạm chấp nhận phương án ấy đi, vậy code của ta chỉ hoạt động trên Excel thôi à?
Tôi thì không nghĩ thế! Nếu đã viết code, tôi sẽ tính đến việc code ấy có thể hoạt động trên mọi môi trường
 
Upvote 0
Nếu sort trên sheet thì sao gọi là Ý TƯỞNG SORT BẰNG ARRAY?
Mai nay bạn định sort trên ListBox bằng cách nào? Đừng nói là copy toàn bộ ra sheet, sort xong cho vô ListBox trở lại nha! Mà cứ cho là tạm chấp nhận phương án ấy đi, vậy code của ta chỉ hoạt động trên Excel thôi à?
Tôi thì không nghĩ thế! Nếu đã viết code, tôi sẽ tính đến việc code ấy có thể hoạt động trên mọi môi trường

Bởi vậy em mới đưa ra nhiều hướng giải quyết cho nhiều phương pháp, nếu có hướng đi đúng biết đâu người có thuật toán cao siêu sẽ rút từ đâu đó những bài mà chúng ta cùng thảo luận thì có thể người đó sẽ làm được việc đó.

Hy vọng người đó là Thầy đấy!
 
Upvote 0
Theo em nghĩ, chỉ cần mã hóa các chữ có dấu tiếng Việt (cả thường và hoa chỉ có 148 ký tự), phương thức Sort trong sheet sẽ làm việc với những phần còn lại, em lại nghĩ sort 2 chiều của Thầy cũng có phương thức sort, vậy thì không cần cả một thư viện ký tự làm chi? Chỉ cần mã hóa cột cần sort, còn những cột khác không cần thiết.

Cũng chẳng ai Sort cái cột có công thức (nếu có sort làm sao đây? còn duyệt luôn thì giá trị true, false cứ theo F trước T sau).

Tôi nghĩ rằng ta chỉ cần thuật toán. Chuyện tập ký tự như thế nào là đủ thì vô cùng. Nhưng nếu ta làm được với một tập ký tự chọn trước thì việc thêm ký tự vào tập cho đầy đủ hơn chả có gì là khó. Ta chỉ cần xếp "tay" lại thứ tự các ký tự trong tập.
Tôi cũng thử làm cho tập ký tự chứa tất cả các ký tự Việt, các chữ số, và các ký tự khác (như + - *, :, ? ...) mà code >= 32 và <= 127. Cho tập này thì tôi mã mỗi ký tự bằng 2 ký tự từ tập A = "0..9" + "abcdef". Tức tôi sắp xếp tập ký tự theo dãy tăng dần và gán cho chúng giá trị từ 0 tới ... nhưng được viết trong hệ 16, như vậy mỗi ký tự được mã bằng 2 ký tự của tập A.
Hàm Sort2DArray nhận mảng đã mã hóa ở các cột cần Sort hoặc không cần mã nếu chúng chỉ chứa các ký tư có code trong khoảng 32..127
Như vậy việc mã hóa là do Caller làm, hàm chỉ làm nhiệm vụ Sort mà thôi. Cũng có thể "đùn" cho hàm chuyện mã hóa bằng cách truyền thông số là cột này chứa Unicode, cột kia Vni ... nhưng như thế không đảm bảo vì có thể người dùng có nhiều loại phông chữ khác nhau trong toàn Sheet. Cũng có thể "đùn" cho hàm chuyện mã hóa mà không truyền thông số, lúc đó hàm tự phải "nhận dạng", "đoán" ký tự. Nhưng như vậy hàm có lẽ phải gọi là "Doan_va_Ma_Hoa thì đúng hơn. Hàm Sort thì như theo tên gọi nó được sinh ra để Sort.
Tôi chọn tập ký tự như đã nói, nhưng nếu ta chọn thêm hàng trăm ký tự khác mà vẫn giữ cách mã như tôi nói thì lúc đó mỗi ký tự cần mã bằng 3 ký tự từ tập A. Việc sắp xếp tập ký tự và gán bộ 3 ký tự ta làm bằng tay. Ta chỉ cung cấp cho người dùng hàm để mã hóa
Hàm Sort trong file đính kèm trả về mảng đã sắp xếp hoàn chỉnh và có thể dùng ngay nếu ta truyền cho hàm mảng không mã hóa (do chứa các ký tự có code 32..127) hoặc trả về mảng "vô giá trị" vì có trả về thì mảng chứa các cột mã hóa nên người dùng phải giải mã. Nhưng khi ta gọi hàm thì ta truyền thêm một mảng 1 chiều chứa thứ tự các dòng. Khi hàm trở về thì mảng này chứa lần lượt chỉ số dòng cần có trong mảng sắp xếp. Có được thứ tự này thì ta xếp được mảng nguồn.
Tôi đã thử test qua thì thấy việc mã hóa chiếm nhiều thời gian. Riêng việc sắp xếp mảng trong Sort2DArray thì "trong nháy mắt". Khi mã hóa thì tôi không kiểm tra phông chữ của từng ký tự vì như thế mất rất nhiều thời gian. Cũng không làm như nhiều người là kiểm tra ký tự đầu trong Sheet rồi coi đó là phông chữ trong toàn Sheet. Tôi kiểm tra từng cell. Vì có thể trong sheet người ta chuyển phông chữ nhiều lần nhưng hiếm ai trong cùng một cell chuyển phông chữ.
Nói tóm lại: việc mã hóa do người dùng làm, ta cung cấp cho người dùng hàm để mã hóa + hàm để sort

Link: http://www.mediafire.com/download.php?cjpwiucm6sj67ww
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi nghĩ rằng ta chỉ cần thuật toán.


Trong tập tin gửi lên vd. dùng để test hàm Sort2DArray có lỗi.
Hàm Sort2DArray trước tiên kiểm tra tính đúng đắn của dữ liệu đầu vào và có dòng:
Mã:
If (UBound(arr_index) - LBound(arr_index) <> UBound(tmpArr, 1) - LBound(tmpArr, 1)) Or _
       (col1 < LBound(tmpArr, 2)) Or (col1 > UBound(tmpArr, 2)) Or _
       (col1 = col2) Or (col1 = col3) Or (col2 = col3) Then GoTo end_
Tức là phải có ít nhất 1 cột có chỉ số nằm trong giới hạn của mảng và 3 cột là khác nhau từng đôi một. Trong khi đó vd. để test hàm có code:
Mã:
Select Case i
            Case 1:
                col1 = CDbl(cot) - Cotdau + 1: col2 = -1: col3 = col2
            Case 2:
                col2 = CDbl(cot) - Cotdau + 1
            Case 3:
                col3 = CDbl(cot) - Cotdau + 1
End Select
tức nếu ta chỉ chọn 1 cột thì col2 = -1 = col3 nên trong hàm Sort2DArray có GoTo end_, và như vậy không sắp xếp được 1 cột. Có thể sửa lại code vd. nhưng tốt hơn là sửa code kiểm tra dữ liệu trong hàm Sort, tức thay
Mã:
If (UBound(arr_index) - LBound(arr_index) <> UBound(tmpArr, 1) - LBound(tmpArr, 1)) Or _
       (col1 < LBound(tmpArr, 2)) Or (col1 > UBound(tmpArr, 2)) Or _
       (col1 = col2) Or (col1 = col3) Or (col2 = col3) Then GoTo end_
bằng
Mã:
    If (UBound(arr_index) - LBound(arr_index) <> UBound(tmpArr, 1) - LBound(tmpArr, 1)) Or _
       (col1 < LBound(tmpArr, 2)) Or (col1 > UBound(tmpArr, 2)) Then GoTo end_
    If col1 = col2 Then
        col2 = LBound(tmpArr, 2) - 1
    ElseIf col1 = col3 Then
        col3 = LBound(tmpArr, 2) - 1
    ElseIf col2 = col3 Then
        col3 = LBound(tmpArr, 2) - 1
    End If

Tất nhiên đó mới chỉ là ý tưởng và bước đầu "cụ thể hóa" ý tưởng đó. Code được viết nhanh "trên đầu gối" nên có thể phải chỉnh sửa để hoàn hảo. Cụ thể mọi người cho ý kiến về chọn "tập ký tự cần thiết". Hiện tôi chọn ký tự Việt và các ký tự khác có code >= 32 và <= 127. Tổng cộng có 212 ký tự được chọn (< 255 nên mỗi ký tự được mã bằng 2 ký tự của tập A). Nếu ai đó thêm ký tự "đặc biệt" thì đề nghị cũng thêm luôn đề xuất xếp nó ở vị trí nào trong tập. Vd. mọi ký tự khác chữ cái được xếp trước. Nhưng thứ tự các ký tự "dấu cách", +, -, *, : {, }, "đặc biệt", ... như thế nào? Cái mấu chốt là thống nhất với nhau về tập ký tự lựa chọn và thứ tự sắp xếp chúng - đại loại là TCGPE giống như TCVN, chứ chuyện mã hóa dữ liệu theo tiêu chuẩn đó không khó.
Như tôi đã nói mọi tập dù có lớn bao nhiêu cũng không thể bao hàm được mọi trường hợp ứng dụng. Vấn đề là chọn sao cho có thể thỏa mãn nhu cầu trong "đa số" (99 %, 90 %, 80 % ...?) các trường hợp. Không có "hàm vạn năng", "tập đầy đủ" ...
 
Lần chỉnh sửa cuối:
Upvote 0
Trong tập tin gửi lên vd. dùng để test hàm Sort2DArray có lỗi.
Hàm Sort2DArray trước tiên kiểm tra tính đúng đắn của dữ liệu đầu vào và có dòng:
Mã:
If (UBound(arr_index) - LBound(arr_index) <> UBound(tmpArr, 1) - LBound(tmpArr, 1)) Or _
       (col1 < LBound(tmpArr, 2)) Or (col1 > UBound(tmpArr, 2)) Or _
       (col1 = col2) Or (col1 = col3) Or (col2 = col3) Then GoTo end_
Tức là phải có ít nhất 1 cột có chỉ số nằm trong giới hạn của mảng và 3 cột là khác nhau từng đôi một. Trong khi đó vd. để test hàm có code:
Mã:
Select Case i
            Case 1:
                col1 = CDbl(cot) - Cotdau + 1: col2 = -1: col3 = col2
            Case 2:
                col2 = CDbl(cot) - Cotdau + 1
            Case 3:
                col3 = CDbl(cot) - Cotdau + 1
End Select
tức nếu ta chỉ chọn 1 cột thì col2 = -1 = col3 nên trong hàm Sort2DArray có GoTo end_, và như vậy không sắp xếp được 1 cột. Có thể sửa lại code vd. nhưng tốt hơn là sửa code kiểm tra dữ liệu trong hàm Sort, tức thay
Mã:
If (UBound(arr_index) - LBound(arr_index) <> UBound(tmpArr, 1) - LBound(tmpArr, 1)) Or _
       (col1 < LBound(tmpArr, 2)) Or (col1 > UBound(tmpArr, 2)) Or _
       (col1 = col2) Or (col1 = col3) Or (col2 = col3) Then GoTo end_
bằng
Mã:
    If (UBound(arr_index) - LBound(arr_index) <> UBound(tmpArr, 1) - LBound(tmpArr, 1)) Or _
       (col1 < LBound(tmpArr, 2)) Or (col1 > UBound(tmpArr, 2)) Then GoTo end_
    If col1 = col2 Then
        col2 = LBound(tmpArr, 2) - 1
    ElseIf col1 = col3 Then
        col3 = LBound(tmpArr, 2) - 1
    ElseIf col2 = col3 Then
        col3 = LBound(tmpArr, 2) - 1
    End If

Tất nhiên đó mới chỉ là ý tưởng và bước đầu "cụ thể hóa" ý tưởng đó. Code được viết nhanh "trên đầu gối" nên có thể phải chỉnh sửa để hoàn hảo. Cụ thể mọi người cho ý kiến về chọn "tập ký tự cần thiết". Hiện tôi chọn ký tự Việt và các ký tự khác có code >= 32 và <= 127. Tổng cộng có 212 ký tự được chọn (< 255 nên mỗi ký tự được mã bằng 2 ký tự của tập A). Nếu ai đó thêm ký tự "đặc biệt" thì đề nghị cũng thêm luôn đề xuất xếp nó ở vị trí nào trong tập. Vd. mọi ký tự khác chữ cái được xếp trước. Nhưng thứ tự các ký tự "dấu cách", +, -, *, : {, }, "đặc biệt", ... như thế nào? Cái mấu chốt là thống nhất với nhau về tập ký tự lựa chọn và thứ tự sắp xếp chúng - đại loại là TCGPE giống như TCVN, chứ chuyện mã hóa dữ liệu theo tiêu chuẩn đó không khó.
Như tôi đã nói mọi tập dù có lớn bao nhiêu cũng không thể bao hàm được mọi trường hợp ứng dụng. Vấn đề là chọn sao cho có thể thỏa mãn nhu cầu trong "đa số" (99 %, 90 %, 80 % ...?) các trường hợp. Không có "hàm vạn năng", "tập đầy đủ" ...


Hàm của bạn rất hay! Hy vọng bạn mở rộng hơn với các mã khác, chẳng hạn VNI hay ABC, như vậy nó tương đối tổng quát hơn.

Cám ơn bạn rất nhiều!
 
Upvote 0
Hàm của bạn rất hay! Hy vọng bạn mở rộng hơn với các mã khác, chẳng hạn VNI hay ABC, như vậy nó tương đối tổng quát hơn.

Cám ơn bạn rất nhiều!

Trong module tôi gọi hàm "ma_hoa_chuoi" để mã hóa dữ liệu ví dụ. Và tôi coi chuỗi là unicode vì tôi biết dữ liệu của tôi là unicode. Làm như thế để test cho nhanh vì mục đích của tôi là test xem code hoạt động như thế nào. Trong thực tế thì phải mã hóa dữ liệu. Hàm "ma_hoa_chuoi" mã hóa dữ liệu với phông chữ cho trước, cả VN3, VNI chứ đâu chỉ unicode. Ngoài ra còn hàm "ma_hoa_cell" nữa. Cũng nằm cùng "chỗ" với Sort2DArray.
Tôi đã giải thích rất nhiều và rõ ràng trong code rồi mà
 
Lần chỉnh sửa cuối:
Upvote 0
Trong module tôi gọi hàm "ma_hoa_chuoi" để mã hóa dữ liệu ví dụ. Và tôi coi chuỗi là unicode vì tôi biết dữ liệu của tôi là unicode. Làm như thế để test cho nhanh vì mục đích của tôi là test xem code hoạt động như thế nào. Trong thực tế thì phải mã hóa dữ liệu. Hàm "ma_hoa_chuoi" mã hóa dữ liệu với phông chữ cho trước, cả VN3, VNI chứ đâu chỉ unicode. Ngoài ra còn hàm "ma_hoa_cell" nữa. Cũng nằm cùng "chỗ" với Sort2DArray.
Tôi đã giải thích rất nhiều và rõ ràng trong code rồi mà

ý tưởng rất hay, nhưng chưa thực dụng,
song, cũng rất cảm ơn bản dù sao cũng làm cho cái topic này không đi lạc chủ đề,
 
Upvote 0
ý tưởng rất hay, nhưng chưa thực dụng,
song, cũng rất cảm ơn bản dù sao cũng làm cho cái topic này không đi lạc chủ đề,

Vấn đề ở đây là mọi người hãy cùng đưa ra ý tưởng, dù hay dù dở nhưng trong mỗi ý tưởng có thể có một vài khía cạnh hay, bổ ích. Cùng chung sức như thế có thể rồi chúng ta sẽ có một kết quả cụ thể. Chứ mãi mãi chúng ta chỉ dừng ở giai đoạn tranh luận: hướng như thế chưa được đâu, không dễ đâu ... thì bao giờ mới có được code cụ thể?

Ngồi buồn kiểm tra lại code tôi phát hiện là trong hàm Sort2DArray có vài chỗ gõ thiếu hoặc nhầm.
Cần phải sửa
Mã:
QuickSort tmpArr, tmp_arr_index, LBound(tmpArr, 1), UBound(tmpArr, 1), col1, col2, col3, [COLOR=#ff0000]1[/COLOR], sortAtoZ1
thành
QuickSort tmpArr, tmp_arr_index, LBound(tmpArr, 1), UBound(tmpArr, 1), col1, col2, col3, [COLOR=#ff0000]col1[/COLOR], sortAtoZ1

Mã:
QuickSort tmpArr, tmp_arr_index, start, finish, col1, col2, col3, [COLOR=#ff0000]2[/COLOR], sortAtoZ2
thành
QuickSort tmpArr, tmp_arr_index, start, finish, col1, col2, col3, [COLOR=#ff0000]col2[/COLOR], sortAtoZ2

Mã:
QuickSort tmpArr, tmp_arr_index, start, finish, col1, col2, col3, [COLOR=#ff0000]3[/COLOR], sortAtoZ3
thành
QuickSort tmpArr, tmp_arr_index, start, finish, col1, col2, col3, [COLOR=#ff0000]col3[/COLOR], sortAtoZ3

Mã:
If [COLOR=#ff0000]U[/COLOR]Bound(tmpArr, 2) <= col3 Then
thành
If [COLOR=#ff0000]L[/COLOR]Bound(tmpArr, 2) <= col3 Then


Tập tin đã sửa có thể tải tại:
Link http://www.mediafire.com/download.php?cjpwiucm6sj67ww
 
Lần chỉnh sửa cuối:
Upvote 0
Không biết là ý tưởng này có kết quả chưa, có thể sort mọi thứ giống như Excel sort?
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom