Excel có lọc để giải toán như sau được không ạ?

Liên hệ QC

mrhh

Thành viên mới
Tham gia
29/10/19
Bài viết
29
Được thích
8
Thưa các anh chị? Em muốn ghép 0,1,2,3,4,5,6,7,8,9 thành (nhóm 5) số có 5 chữ số khác nhau Ví dụ: 12345 sẽ tính một nhóm, 54321 vẫn là nhóm đó, 23451 ... vẫn là nhóm đó. tóm lại các số có chứa 12345 dù có đảo vị trí số khác đi nhưng vẫn là 1 nhóm đó.
Liệu excel có giải quyết được xem có bao nhiêu nhóm như này không? Có tổng hợp hết các nhóm ra được không ạ?

Nói cách khác là tìm tất cả các số có 5 chữ số và lọc chúng nhóm lại thành các nhóm có 5 chữ số giống nhau ạ? viết các nhóm đó ra như nào?

Nếu không thấy liên quan anh tới excell anh chị bỏ qua giúp.
 
Tìm trong diễn đàn, các từ khoá "hcinhr hợp", "tổ hợp" permutation, combination.
 
Xin lỗi, đúng là chỉnh hợp.

Gú gồ nguyên dòng như sau:
"chỉnh hợp" "tổ hợp" giaiphapexcel
 
Thưa các anh chị? Em muốn ghép 0,1,2,3,4,5,6,7,8,9 thành (nhóm 5) số có 5 chữ số khác nhau Ví dụ: 12345 sẽ tính một nhóm, 54321 vẫn là nhóm đó, 23451 ... vẫn là nhóm đó. tóm lại các số có chứa 12345 dù có đảo vị trí số khác đi nhưng vẫn là 1 nhóm đó.
Liệu excel có giải quyết được xem có bao nhiêu nhóm như này không? Có tổng hợp hết các nhóm ra được không ạ?

Nói cách khác là tìm tất cả các số có 5 chữ số và lọc chúng nhóm lại thành các nhóm có 5 chữ số giống nhau ạ? viết các nhóm đó ra như nào?

Nếu không thấy liên quan anh tới excell anh chị bỏ qua giúp.
"Liệu excel có giải quyết được xem có bao nhiêu nhóm như này không": Dùng hàm permut()
 
Trường hợp của bạn là tổ hợp chập 5 của 10 = 10/(5! * (10-5)!) = 10!/(5! * 5!) = 252.
Trong Excel trên trang tính là công thức
Mã:
=COMBIN(10;5)
Trường hợp của bạn phải là COMBIN chứ không phải là PERMUT.
 
Em tìm trên Google cũng ra nhưng đọc chưa được hiểu cho lắm!
Tức là bạn đã có ít nhất 1 kết quả tìm kiếm? Thì đưa lên GPE rồi hỏi những chỗ bạn chưa hiểu. Chứ bây giờ ai đó đưa ra 1 giải pháp thì rồi bạn cũng sẽ nói là không hiểu.

Ở mức độ của bạn thì bạn chỉ muốn có giải pháp, bạn không bàn về tối ưu của code. Vì muốn tối ưu thì trước hết phải biết làm cho ra một kết quả. Mà bạn thì chưa biết làm.

Ta thống nhất với nhau là chỉ tìm 1 giải pháp, không bàn tới tối ưu.
1. Khái niệm.
Với mỗi 5 chữ số khác nhau từng đôi một có thể lập được 5! = 120 số khác nhau. 120 số này ta gọi là trùng nhau do được lập từ cùng 5 chữ số cho trước. 2 số khác nhau ít nhất 1 chữ số thì ta gọi là không trùng nhau.
2.
Bài toán của bạn là tìm những số có 5 chữ số khác nhau từng đôi một từ tập 10 chữ số 0, 1, ..., 9 nhưng không trùng nhau. Số các số như thế là tổ hợp chập 5 của 10 = 10/(5! * (10-5)!) = 10!/(5! * 5!) = 252

Vấn đề là liệt kê các số.
Như ta đã biết, với mỗi 5 chữ số khác nhau từng đôi một cho trước có thể lập được 120 số trùng nhau (khái niệm trùng nhau). Ta lấy ra 1 số làm kết quả. Ta lấy số lớn nhất trong 120 số đó. Vd. từ 5 chữ số 1, 2, 3, 4 và 5 có 120 số: 12345, 12354, ..., 54321. Ta lấy số 54321. Số mà ta lấy có tính chất: chữ số hàng đơn vị < chữ số hàng chục, chữ số hàng chục < chữ số hàng trăm, ..., chữ số hàng nghì < chữ số hàng chục nghìn.
Số nhỏ nhất cần lấy là 43210, số lớn nhất là 98765.

Code "cần cù" 1.
Mã:
Sub test()
Dim k As Long, so As Long, dk As Boolean, Arr()
    ReDim Arr(1 To 252, 1 To 1)
    so = 43210
    Do While so <= 98765
        dk = (Mid(so, 1, 1) > Mid(so, 2, 1)) And (Mid(so, 2, 1) > Mid(so, 3)) And (Mid(so, 3, 1) > Mid(so, 4, 1)) And (Mid(so, 4, 1) > Mid(so, 5, 1))
        If dk Then
            k = k + 1
            Arr(k, 1) = so
        End If
        so = so + 1
    Loop
    Range("A1").Resize(k).Value = Arr
End Sub
Như thế ta cứ "cần cù" xét các số liên tiếp, bắt đầu từ số 43210, với mỗi số ta tính và xét điều kiện cần có đã nói ở trên. Nếu thỏa điều kiện thì lấy vào mảng.
Như vậy thì code phải là dễ hiểu và bạn không có quyền nói: "nhưng đọc chưa được hiểu cho lắm"

Cách cần cù phải xét tất cả các số trong khoảng, và với mỗi số phải tính và xét điều kiện. Vì thế cách trên chưa tối ưu.

Bạn có thể xét 5 vòng FOR lồng nhau - vòng FOR n lấy ra chữ số cho vị trí n, với n = 1, 2, ..., 5.

Code 5 FOR sẽ nhanh hơn rất nhiều. Coi như đây là bài tập cho bạn.
 
Tức là bạn đã có ít nhất 1 kết quả tìm kiếm? Thì đưa lên GPE rồi hỏi những chỗ bạn chưa hiểu. Chứ bây giờ ai đó đưa ra 1 giải pháp thì rồi bạn cũng sẽ nói là không hiểu.

Ở mức độ của bạn thì bạn chỉ muốn có giải pháp, bạn không bàn về tối ưu của code. Vì muốn tối ưu thì trước hết phải biết làm cho ra một kết quả. Mà bạn thì chưa biết làm.

Ta thống nhất với nhau là chỉ tìm 1 giải pháp, không bàn tới tối ưu.
1. Khái niệm.
Với mỗi 5 chữ số khác nhau từng đôi một có thể lập được 5! = 120 số khác nhau. 120 số này ta gọi là trùng nhau do được lập từ cùng 5 chữ số cho trước. 2 số khác nhau ít nhất 1 chữ số thì ta gọi là không trùng nhau.
2.
Bài toán của bạn là tìm những số có 5 chữ số khác nhau từng đôi một từ tập 10 chữ số 0, 1, ..., 9 nhưng không trùng nhau. Số các số như thế là tổ hợp chập 5 của 10 = 10/(5! * (10-5)!) = 10!/(5! * 5!) = 252

Vấn đề là liệt kê các số.
Như ta đã biết, với mỗi 5 chữ số khác nhau từng đôi một cho trước có thể lập được 120 số trùng nhau (khái niệm trùng nhau). Ta lấy ra 1 số làm kết quả. Ta lấy số lớn nhất trong 120 số đó. Vd. từ 5 chữ số 1, 2, 3, 4 và 5 có 120 số: 12345, 12354, ..., 54321. Ta lấy số 54321. Số mà ta lấy có tính chất: chữ số hàng đơn vị < chữ số hàng chục, chữ số hàng chục < chữ số hàng trăm, ..., chữ số hàng nghì < chữ số hàng chục nghìn.
Số nhỏ nhất cần lấy là 43210, số lớn nhất là 98765.

Code "cần cù" 1.
Mã:
Sub test()
Dim k As Long, so As Long, dk As Boolean, Arr()
    ReDim Arr(1 To 252, 1 To 1)
    so = 43210
    Do While so <= 98765
        dk = (Mid(so, 1, 1) > Mid(so, 2, 1)) And (Mid(so, 2, 1) > Mid(so, 3)) And (Mid(so, 3, 1) > Mid(so, 4, 1)) And (Mid(so, 4, 1) > Mid(so, 5, 1))
        If dk Then
            k = k + 1
            Arr(k, 1) = so
        End If
        so = so + 1
    Loop
    Range("A1").Resize(k).Value = Arr
End Sub
Như thế ta cứ "cần cù" xét các số liên tiếp, bắt đầu từ số 43210, với mỗi số ta tính và xét điều kiện cần có đã nói ở trên. Nếu thỏa điều kiện thì lấy vào mảng.
Như vậy thì code phải là dễ hiểu và bạn không có quyền nói: "nhưng đọc chưa được hiểu cho lắm"

Cách cần cù phải xét tất cả các số trong khoảng, và với mỗi số phải tính và xét điều kiện. Vì thế cách trên chưa tối ưu.

Bạn có thể xét 5 vòng FOR lồng nhau - vòng FOR n lấy ra chữ số cho vị trí n, với n = 1, 2, ..., 5.

Code 5 FOR sẽ nhanh hơn rất nhiều. Coi như đây là bài tập cho bạn.
Vâng em hiểu rồi cảm ơn các bác ạ!
 
Lần chỉnh sửa cuối:
Nhưng ý tôi là đó là bài tập cho bạn. Bạn thử giải. Được hay không đều phải trình báo. Nếu bí phần nào thì hỏi để mọi người hướng dẫn. Thế mới là học.
Nói thực là em mới đọc, xem qua VBA thôi, coi như chỉ hiểu về BVA là nhũng đoạn code phục vụ cho công việc trong excell, (có vẻ VBA cũng na ná giống mấy ngôn nhữ lập trình khác) Nhưng bài tập này để em tự code chắc lâu lắm, mà chắc gì đã làm được!
Qua đây em mới thấy khả năng của Excell là vô cùng rộng lớn! Các bác cũng thật siêu!
Chốt lại vụ File kia của em, chốt lại là ko đưa vào công thức được. Phải dùng BVA đúng không ạ? Nếu code nhanh được thì bác code cho em phát để em học dần. :(.... Còn nó qua lằng ngoằng, mất nhiều thời gian của bác thì thôi! Cảm ơn rất nhiều vì bác đã nhiệt tình!
 

File đính kèm

  • Liệt kê tổ hợp.xlsx
    10.1 KB · Đọc: 11
Nếu code nhanh được thì bác code cho em phát để em học dần. :(.... Còn nó qua lằng ngoằng, mất nhiều thời gian của bác thì thôi! Cảm ơn rất nhiều vì bác đã nhiệt tình!
Thôi được, đã trót gợi ý 5 FOR thì tôi công bố vậy.
Mã:
Sub test1()
'    nhanh hon test
    Dim k As Long, k1 As Long, k2 As Long, k3 As Long, k4 As Long, k5 As Long, Arr(), t
    t = Timer
    ReDim Arr(1 To 252, 1 To 1)
    For k1 = 0 To 5
        For k2 = k1 + 1 To 6
            For k3 = k2 + 1 To 7
                For k4 = k3 + 1 To 8
                    For k5 = k4 + 1 To 9
                        k = k + 1
                        Arr(k, 1) = k5 & k4 & k3 & k2 & k1
                    Next k5
                Next k4
            Next k3
        Next k2
    Next k1
    Range("B1").Resize(k).Value = Arr
End Sub
Ta chọn từ mỗi nhóm 1 số lớn nhất. Số này có dạng k5k4k3k2k1, trong đó k1 < k2 < k3 < k4 < k5 là những chữ số.
k1 < k2 < k3 < k4 < k5 là điều kiện.

Tại sao k1 chỉ có thể nhận các giá trị từ 0 đến 5. Vì nếu k1 nhận giá trị ít nhất là 6, thì từ điều kiện có k2, k3, k4 ít nhất phải là 7, 8, 9. Điều này là không thể vì k4 < k5 <= 9.

k2 nhận giá trị từ k1+1 để thỏa điều kiện k1 < k2. k2 nhận giá trị lớn nhất là 6, vì nếu k2 nhận ít nhất là giá trị 7 thí ít nhất k3, k4 phải là 8, 9. Cũng không thể vì k4 < k5 <= 9.

Lúc này thì tự bạn có thể trả lời vì sao có For k3 = ..., For k4 = ... và For k5 = ...

Các kết quả ở code dùng DO ... LOOP đã được sắp xếp tăng dần. Các kết quả ở code này không được sắp xếp. Nếu bạn sắp xếp tăng dần bằng công cụ của Excel thì sẽ thấy 2 kết quả như nhau.
 
Thôi được, đã trót gợi ý 5 FOR thì tôi công bố vậy.
Mã:
Sub test1()
'    nhanh hon test
    Dim k As Long, k1 As Long, k2 As Long, k3 As Long, k4 As Long, k5 As Long, Arr(), t
    t = Timer
    ReDim Arr(1 To 252, 1 To 1)
    For k1 = 0 To 5
        For k2 = k1 + 1 To 6
            For k3 = k2 + 1 To 7
                For k4 = k3 + 1 To 8
                    For k5 = k4 + 1 To 9
                        k = k + 1
                        Arr(k, 1) = k5 & k4 & k3 & k2 & k1
                    Next k5
                Next k4
            Next k3
        Next k2
    Next k1
    Range("B1").Resize(k).Value = Arr
End Sub
Ta chọn từ mỗi nhóm 1 số lớn nhất. Số này có dạng k5k4k3k2k1, trong đó k1 < k2 < k3 < k4 < k5 là những chữ số.
k1 < k2 < k3 < k4 < k5 là điều kiện.

Tại sao k1 chỉ có thể nhận các giá trị từ 0 đến 5. Vì nếu k1 nhận giá trị ít nhất là 6, thì từ điều kiện có k2, k3, k4 ít nhất phải là 7, 8, 9. Điều này là không thể vì k4 < k5 <= 9.

k2 nhận giá trị từ k1+1 để thỏa điều kiện k1 < k2. k2 nhận giá trị lớn nhất là 6, vì nếu k2 nhận ít nhất là giá trị 7 thí ít nhất k3, k4 phải là 8, 9. Cũng không thể vì k4 < k5 <= 9.

Lúc này thì tự bạn có thể trả lời vì sao có For k3 = ..., For k4 = ... và For k5 = ...

Các kết quả ở code dùng DO ... LOOP đã được sắp xếp tăng dần. Các kết quả ở code này không được sắp xếp. Nếu bạn sắp xếp tăng dần bằng công cụ của Excel thì sẽ thấy 2 kết quả như nhau.
Chân thành cảm ơn sự nhiệt tình chia sẻ của bác!
Em đã dăng kí học1 khóa excell online, nhưng nói thực diễn đàn này là một thầy giáo vô cùng gần gũi về mặt giao tiếp và sâu, đa dạng về mặt kiến thức.
 
Chân thành cảm ơn sự nhiệt tình chia sẻ của bác!
Em đã dăng kí học1 khóa excell online, nhưng nói thực diễn đàn này là một thầy giáo vô cùng gần gũi về mặt giao tiếp và sâu, đa dạng về mặt kiến thức.
Mới học Excel online mà động lại càng bài như thế này, thì toi, nhanh bị rối. Tốt nhất lấy code áp dụng và quên đi. Học theo bài dần dần vậy, bao giờ đủ lực thì đọc lại.
 
Mới học Excel online mà động lại càng bài như thế này, thì toi, nhanh bị rối.
Thực ra học Excel hay gì chăng nữa, lập trình trước hết là tư duy. Phải tìm ra hướng đi. Sau đó thì trong từng ngôn ngữ cụ thể tìm công cụ để thực hiện thuật toán đã tìm ra ở bước 1. Tư duy trong bài này không liên quan gì tới Excel. Tôi xử lý vấn đề như sau. Tôi chọn trong mỗi nhóm 1 số lớn nhất. Chọn như thế để dễ xác định "tính chất" của số cần tìm. Vì là số lớn nhất trong mỗi nhóm nên hàng đơn vị < hàng chục < hàng trăm < hàng nghìn < hàng chục nghìn. Nếu số đó gọi là k5k4k3k2k1 với k1, ..., k5 là các chữ số thì k1 < k2 < ... < k5. Dễ thấy số lớn nhất là 98765, nhỏ nhất là 43210. Vậy thì xét từng số từ nhỏ nhất tới lớn nhất và xét tính chất của từng số thì ta sẽ có kết quả thôi. Tư duy đã mang lại thuật toán của code Do ... Loop. Tư duy này không dính dáng gì tới Excel. Bất kể ai có tư duy tốt đều tìm ra thuật toán dù không biết Excel, không biết lập trình. Chỉ khi cần thực hiện thuật toán mới cần một ngôn ngữ cụ thể. Mục đích là để dịch thuật toán, dịch ngôn ngữ của con người thành ngôn ngữ của máy để thực hiện.
Ta chọn VBA với cấu trúc Do ... Loop. Khai báo biến và sử dụng các trúc của ngôn ngữ như Do ... Loop, For ... Next, các cấu trúc dữ liệu có trong ngôn ngữ cụ thể, lại đúng là cơ bản của cơ bản, và phải học trong những bài đầu tiên. Người mới học đã phải biết những cái này.

Sau đó trong vd. VBA thì mới tìm hiểu cấu trúc của trang tính, bảng tính về mặt đối tượng, hiểu thế nào là lập trình hướng đối tượng. Đó mới là những bài về sau. Sách nào, thầy nào mà ngay những bài đầu tiên đã cho học các ví dụ thực tế cụ thể để hiện thông báo, nhập dữ liệu vào cell, đổi mầu chữ thì chỉ là cho con cá, dạy 1 biết 1, biết cái đã học mà không thể tự mình biến tấu, khai triển thêm. Vì học trò đã biết những cái căn bản đâu. Thậm chí chưa biết khi nào dùng hàm, chưa nói tới chuyện hiểu, đối tượng là gì, lập trình hướng đối tượng là gì, cấu trúc trang tính, bảng tính ra sao.
 
Thực ra học Excel hay gì chăng nữa, lập trình trước hết là tư duy. Phải tìm ra hướng đi. Sau đó thì trong từng ngôn ngữ cụ thể tìm công cụ để thực hiện thuật toán đã tìm ra ở bước 1. Tư duy trong bài này không liên quan gì tới Excel. Tôi xử lý vấn đề như sau. Tôi chọn trong mỗi nhóm 1 số lớn nhất. Chọn như thế để dễ xác định "tính chất" của số cần tìm. Vì là số lớn nhất trong mỗi nhóm nên hàng đơn vị < hàng chục < hàng trăm < hàng nghìn < hàng chục nghìn. Nếu số đó gọi là k5k4k3k2k1 với k1, ..., k5 là các chữ số thì k1 < k2 < ... < k5. Dễ thấy số lớn nhất là 98765, nhỏ nhất là 43210. Vậy thì xét từng số từ nhỏ nhất tới lớn nhất và xét tính chất của từng số thì ta sẽ có kết quả thôi. Tư duy đã mang lại thuật toán của code Do ... Loop. Tư duy này không dính dáng gì tới Excel. Bất kể ai có tư duy tốt đều tìm ra thuật toán dù không biết Excel, không biết lập trình. Chỉ khi cần thực hiện thuật toán mới cần một ngôn ngữ cụ thể. Mục đích là để dịch thuật toán, dịch ngôn ngữ của con người thành ngôn ngữ của máy để thực hiện.
Ta chọn VBA với cấu trúc Do ... Loop. Khai báo biến và sử dụng các trúc của ngôn ngữ như Do ... Loop, For ... Next, các cấu trúc dữ liệu có trong ngôn ngữ cụ thể, lại đúng là cơ bản của cơ bản, và phải học trong những bài đầu tiên. Người mới học đã phải biết những cái này.

Sau đó trong vd. VBA thì mới tìm hiểu cấu trúc của trang tính, bảng tính về mặt đối tượng, hiểu thế nào là lập trình hướng đối tượng. Đó mới là những bài về sau. Sách nào, thầy nào mà ngay những bài đầu tiên đã cho học các ví dụ thực tế cụ thể để hiện thông báo, nhập dữ liệu vào cell, đổi mầu chữ thì chỉ là cho con cá, dạy 1 biết 1, biết cái đã học mà không thể tự mình biến tấu, khai triển thêm. Vì học trò đã biết những cái căn bản đâu. Thậm chí chưa biết khi nào dùng hàm, chưa nói tới chuyện hiểu, đối tượng là gì, lập trình hướng đối tượng là gì, cấu trúc trang tính, bảng tính ra sao.
Vâng em cảm ơn nhiều đến sự nhiệt tình của các bác! Em sẽ lưu ý nhắc nhở này!
 
NHỜ CÁC BẠN CAO THỦ GIÚP ĐẾM SỐ LẦN XUẤT HIỆN CỦA SỐ 1 HOẶC SỐ 0 TRONG 1 CỘT A
(FILE ĐÍNH KÈM)
CẢM TẠ
 

File đính kèm

  • TÍNH SỐ LẦN XUẤT HIỆN.xlsx
    10.4 KB · Đọc: 11
NHỜ CÁC BẠN CAO THỦ GIÚP ĐẾM SỐ LẦN XUẤT HIỆN CỦA SỐ 1 HOẶC SỐ 0 TRONG 1 CỘT A
(FILE ĐÍNH KÈM)
CẢM TẠ
H2
Mã:
=IF(AND(A3=A4;A4<>"");"";ROWS(H$2:H3)-LOOKUP(2;1/(H$2:H2<>"");ROW($1:$100)))
Kéo sang phải tới cột N rồi xuống dưới.

Công thức lợi dụng H2:N2 <> "", tức sẽ sai khi H2:N2 = "".
 
nhờ anh giúp dùm em
Bài đã được tự động gộp:

H2
Mã:
=IF(AND(A3=A4;A4<>"");"";ROWS(H$2:H3)-LOOKUP(2;1/(H$2:H2<>"");ROW($1:$100)))
Kéo sang phải tới cột N rồi xuống dưới.

Công thức lợi dụng H2:N2 <> "", tức sẽ sai khi H2:N2 = "".
nhờ anh giúp dùm em 1 vé nữa anh nhé
 

File đính kèm

  • vd tự động điền.png
    vd tự động điền.png
    55.9 KB · Đọc: 24
  • phân tách 1 số ra thành nhiều số nhiều cột.xlsx
    9.5 KB · Đọc: 7
Web KT
Back
Top Bottom