Phản Hồi #2
=RANDBETWEEN(A1,A2) &"-"& RANDBETWEEN(A3,A4)&"-"& RANDBETWEEN(A5,A6)&"-"& RANDBETWEEN(A7,A8)&"-"& RANDBETWEEN(A9,A10)&.....
Đơn giản quá nhỉ
Published Time: Mon, 06 Apr 2026 14:04:41 GMT
Chào các anh chị. Cho em hỏi bài toán như sau
Cho 1 danh sách gồm 20 cái tên khác nhau, yêu cầu nhấc ra 1 tổ hợp gồm 10 tên ngẫu nhiên trong danh sách 20 tên đó, sao cho không có cái tên nào trong cùng 1 tổ hợp bị trùng nhau. Kết quả nằm trong 1 cell và các tên ngăn nhau bằng dấu trừ.
Nhờ anh chị cho em xin công thức ạ. Em xin cảm ơn nhiều!
=RANDBETWEEN(A1,A2) &"-"& RANDBETWEEN(A3,A4)&"-"& RANDBETWEEN(A5,A6)&"-"& RANDBETWEEN(A7,A8)&"-"& RANDBETWEEN(A9,A10)&.....
Đơn giản quá nhỉ
Chào các anh chị. Cho em hỏi bài toán như sauCho 1 danh sách gồm 20 cái tên khác nhau, yêu cầu nhấc ra 1 tổ hợp gồm 10 tên ngẫu nhiên trong danh sách 20 tên đó, sao cho không có cái tên nào trong cùng 1 tổ hợp bị trùng nhau. Kết quả nằm trong 1 cell và các tên ngăn nhau bằng dấu trừ.
Nhờ anh chị cho em xin công thức ạ. Em xin cảm ơn nhiều!
Bạn thử code này:
Mã:
Sub a() Dim arr, num As Long, key, str As String arr = [A1:A20] With CreateObject("Scripting.dictionary") Do While .Count < 10 Randomize num = Int(Rnd() * 20) + 1 If Not .exists(num) Then .Add num, arr(num, 1) Loop str = Join(.items(), " - ") End With [c1].Value = str End SubLần chỉnh sửa cuối: 23/1/19
Chào các anh chị. Cho em hỏi bài toán như sauCho 1 danh sách gồm 20 cái tên khác nhau, yêu cầu nhấc ra 1 tổ hợp gồm 10 tên ngẫu nhiên trong danh sách 20 tên đó, sao cho không có cái tên nào trong cùng 1 tổ hợp bị trùng nhau. Kết quả nằm trong 1 cell và các tên ngăn nhau bằng dấu trừ.
Nhờ anh chị cho em xin công thức ạ. Em xin cảm ơn nhiều!
Nếu không nối chuỗi có thể dùng công thức này:
=INDEX($A$1:$A$20,SMALL(IF(COUNTIF($E$1:E1,$A$1:$A$20)=0,ROW($1:$20)),RANDBETWEEN(1,21-COLUMN(A1))))
Bấm Ctrl+Shift+Enter rồi kéo sang phải.
Bạn thử code này:Mã:
Sub a() Dim arr, num As Long, key, str As String arr = [A1:A20] With CreateObject("Scripting.dictionary") Do While .Count < 10 Randomize num = Int(Rnd() * 20) + 1 If Not .exists(num) Then .Add num, "" Loop For Each key In .keys() str = str & IIf(str = "", "", " - ") & arr(key, 1) Next End With [c1].Value = str End Sub
Thử dùng Join cho đẹp
Thử dùng Join cho đẹp
Đã sữa, thanks bạn!
Chào các anh chị. Cho em hỏi bài toán như sauCho 1 danh sách gồm 20 cái tên khác nhau, yêu cầu nhấc ra 1 tổ hợp gồm 10 tên ngẫu nhiên trong danh sách 20 tên đó, sao cho không có cái tên nào trong cùng 1 tổ hợp bị trùng nhau. Kết quả nằm trong 1 cell và các tên ngăn nhau bằng dấu trừ.
Nhờ anh chị cho em xin công thức ạ. Em xin cảm ơn nhiều!
Dùng hàm tự tạo
Mã:
Function GPE(ByVal Rng As Range, ByVal n As Long) Dim Str As String, tmp As String, m As Long, i As Long, j As Long m = Rng.Rows.Count Str = "- " & Join(Application.Transpose(Rng), " - ") & " -" Randomize For i = 1 To m - n num = Int(Rnd() * (m + 1 - i)) + 1 tmp = Replace(Str, "-", "#", 1, num) j = InStrRev(tmp, "#") Str = Replace(Str, Mid(tmp, j + 1, InStr(1, tmp, "-") - j), "") Next i GPE = Mid(Str, 3, Len(Str) - 4) End FunctionSao bạn không hỏi thêm tổ hợp.
Nếu hoán vị 20 cái tên vào 10 vị vị trí khác nhau thì thành bài toán tổ hợp.
Cảm ơn anh @HieuCD và @excel_lv1.5 nhiều ạ. Đúng là chỉ có VBA mới giải quyết được mà em thì chưa thạo.
Theo như em nhớ hồi lớp 11 học thì đây gọi tổ hợp chập 10 của 20, tức là có tối đa 184756 cell kết quả có thể được tạo ra.
=> Do đó em muốn khi kéo ô B1 xuống bên dưới nhiều nhiều nữa thì sẽ xuất ra 1 loạt tổ hợp nhấc 10 phần tử ngẫu nhiên không lặp lại trong số 20 phần tử cho trước ở cột A ạ. Mong anh cho em xin giải pháp, em cảm ơn nhiều ạ!
Vấn đề này có ít nhất là 3 cách giải quyết:
Chú: thuật toán ở bài #3 giản dị nhưng nếu (n-k)/n là số rất nhỏ, tức là k gần bằng n thì khả năng chạm số càng lúc càng cao và theo lý thuyết, bài toán có thể chạy vòng đi vòng lại khá lâu. Yêu cầu bài này (n-k)/n = 0,5 là số tương đối chấp nhận.
Vấn đề này có ít nhất là 3 cách giải quyết:
- cách dễ nhất, và nếu là bài tập thì chính là cách mà Thầy/Cô đòi hỏi: đặt một hàm Rand() vào cột kế bên, sort, lấy ra 10 cái.
- dùng công thức khủng: tôn chỉ của tôi là công thức khủng chỉ dùng để vận động đầu óc giải đố mẹo. Vì vậy toi khong tiếp thêm.
- dùng hàm tự tạo. Thuật toán lấy k phần tử ngẫu nhiên trong n phần tử đã được giải nhiều lần ở diễn đàn này rồi.
Chú: thuật toán ở bài #3 giản dị nhưng nếu (n-k)/n là số rất nhỏ, tức là k gần bằng n thì khả năng chạm số càng lúc càng cao và theo lý thuyết, bài toán có thể chạy vòng đi vòng lại khá lâu. Yêu cầu bài này (n-k)/n = 0,5 là số tương đối chấp nhận.
Lỗi tại em chưa hỏi hết ý ngay từ đầu ạ, em muốn render ra 1 loạt kết quả theo cách kéo B1 xuống dưới thì có thể tạo thêm các tổ hợp mới. Nên em nhờ các anh chị giúp em phần công thức để chạy ạ
Cảm ơn anh @@HieuCD và @@excel_lv1.5 nhiều ạ. Đúng là chỉ có VBA mới giải quyết được mà em thì chưa thạo.Theo như em nhớ hồi lớp 11 học thì đây gọi tổ hợp chập 10 của 20, tức là có tối đa 184756 cell kết quả có thể được tạo ra.
=> Do đó em muốn khi kéo ô B1 xuống bên dưới nhiều nhiều nữa thì sẽ xuất ra 1 loạt tổ hợp nhấc 10 phần tử ngẫu nhiên không lặp lại trong số 20 phần tử cho trước ở cột A ạ. Mong anh cho em xin giải pháp, em cảm ơn nhiều ạ!
Tôi đã nói là thuật toán tạo tổ hợp đã từng được bàn cặn kẽ ở diễn đàn này. Chịu khó tìm.
Số lớn thì khó chứ 30 phần tử trở xuống thì tương đối dễ.
Tôi đã nói là thuật toán tạo tổ hợp đã từng được bàn cặn kẽ ở diễn đàn này. Chịu khó tìm.Số lớn thì khó chứ 30 phần tử trở xuống thì tương đối dễ.
thực ra là em muốn nhờ mọi người cho xin 1 công thức/code để sau nhập nhiều phần tử cho trước hơn, có thể tới 50 phần tử cung cấp sẵn và nhấc ra 10 phần tử ạ
Cảm ơn anh @HieuCD và @excel_lv1.5 nhiều ạ. Đúng là chỉ có VBA mới giải quyết được mà em thì chưa thạo.Theo như em nhớ hồi lớp 11 học thì đây gọi tổ hợp chập 10 của 20, tức là có tối đa 184756 cell kết quả có thể được tạo ra.
=> Do đó em muốn khi kéo ô B1 xuống bên dưới nhiều nhiều nữa thì sẽ xuất ra 1 loạt tổ hợp nhấc 10 phần tử ngẫu nhiên không lặp lại trong số 20 phần tử cho trước ở cột A ạ. Mong anh cho em xin giải pháp, em cảm ơn nhiều ạ!
Thử code này, show tối đa số dòng của excel trong một cột thôi, thay đổi ô B1 để thay đổi số tổ hợp!
Mã:
Sub combin() Dim i As Long, j As Long, n As Long, m As Long, arr, darr, result, str As String If [g1] <> "" Then Range("G1").CurrentRegion.Clear arr = Range("A1:A" & [A100000].End(xlUp).Row): m = UBound(arr): n = [b1] ReDim darr(1 To WorksheetFunction.combin(UBound(arr), n), 1 To n + 2) For i = 1 To UBound(darr, 2) - 2 darr(1, i + 1) = i Next i For i = 2 To UBound(darr) For j = 2 To UBound(darr, 2) - 1 darr(i, j) = IIf(darr(i - 1, j) = m + j - n - 1, CDbl(darr(i, j - 1)) + 1, _ IIf(darr(i - 1, j + 1) = m + j - n Or CDbl(darr(i - 1, j + 1)) = 0,