Hỏi cách lấy số ngẫu nhiên từ hai số cho trước và xuất hiện theo số lần quy định (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

tieulongphi

Thành viên mới
Tham gia
25/9/07
Bài viết
8
Được thích
3
Mình có bài tập như thế này: cho xuất hiện ngẫu nhiên các số trong khoảng (a,b) cho trước và mỗi số có số lần xuất hiện là c Ví dụ: tại cột G cho xuất hiện các số ngẫu nhiên từ 23000 đến 23100 và mỗi số xuất hiện 8 lần (các số này có thể thay đổi) Nhờ các cao thủ giúp giùm, dùng hàm hoặc VBA đều được. Xin cám ơn ạ!
 
Hình như bạn đã có hỏi bài tương tự thì fải(?)

PHP:
Option Explicit
Sub NgauNhien100()
 Dim J As Long, Num As Byte, StrC As String, W As Byte, Z As Integer
1 'Tao Chuoi Só Càn Có:'
 For J = 0 To 99
    StrC = StrC & Right("0" & CStr(J), 2)
 Next J
 [g1].Value = "GPE.COM"
 [g1].CurrentRegion.Offset(1).Clear
 For W = 1 To 8
2 'Xáo Tron Chuoi:'
    For J = 1 To (65534 - 50 * W ^ 2)
        Num = 60 * Rnd() \ 1
        If Num Mod 2 = 0 Then Num = Num + 1
        StrC = Mid(StrC, Num + 12, 200) & Mid(StrC, Num, 12) & Left(StrC, Num - 1)
    Next J
3 'Cát Chuoi & Ghép:'
    For Z = 0 To 99
        [G999].End(xlUp).Offset(1).Value = 23000 + CByte(Mid(StrC, Z + 1, 2))
    Next Z
 Next W
End Sub
 
PHP:
Option Explicit
Sub NgauNhien100()
 Dim J As Long, Num As Byte, StrC As String, W As Byte, Z As Integer
1 'Tao Chuoi Só Càn Có:'
 For J = 0 To 99
    StrC = StrC & Right("0" & CStr(J), 2)
 Next J
 [g1].Value = "GPE.COM"
 [g1].CurrentRegion.Offset(1).Clear
 For W = 1 To 8
2 'Xáo Tron Chuoi:'
    For J = 1 To (65534 - 50 * W ^ 2)
        Num = 60 * Rnd() \ 1
        If Num Mod 2 = 0 Then Num = Num + 1
        StrC = Mid(StrC, Num + 12, 200) & Mid(StrC, Num, 12) & Left(StrC, Num - 1)
    Next J
3 'Cát Chuoi & Ghép:'
    For Z = 0 To 99
        [G999].End(xlUp).Offset(1).Value = 23000 + CByte(Mid(StrC, Z + 1, 2))
    Next Z
 Next W
End Sub

Tôi không chắc giải pháp này chạy ra đúng. Tôi thử thì thấy có một số trị ra trên/dưới 8 lần.

Cách làm đại khái như vầy:

Ví dụ có m số, mỗi số cần ra n lần.
- Tạo mảng m*n phần tử
- Ghi n lần vào mảng; mỗi lằn từ số bắt đầu -> số bắt đầu + m - 1.
Theo ví dụ trên thì mảng có 808 phần tử; ghi 8 lần từ 23000 đến 23100
- Xáo trộn mảng theo hướng ngẫu nhiên

Có 2 cách dễ nhất để xáo trộn mảng:
1. Đi lần lượt từ đầu mảng, dùng hàm Rnd để tìm ra một vị trí kể từ vị trí này đến cuối mảng. Hoán vị hai phần tử.
2. Tạo một dãy M*n số Rnd (số nguyên), đem số này ghép với vị trí mảng (ghép theo kiểu chuõi hay số đều được). Sắp xếp chúng lại, và tách phần vị trí ra để ghi.
 
Mã:
Sub t()
[COLOR=#008000]' hàm demo lấy các số ngẫu nhiên giữa 2 khoảng (23000-23100), mỗi số 8 lần[/COLOR]
[COLOR=#008000]' bài này dùng giải thuật lấy các trị tuần tự và  ghép số random vào đầu trị để sort, sau khi sort xong thì lại tách ra
' như vậy kết quả có thể coi như có thứ tự ngẫu nhiên
[/COLOR]Const fmtRnd = "0.000000" [COLOR=#008000]' format chuỗi random[/COLOR]
Dim soDau As Long, soCuoi As Long, soLuot As Long
soDau = 23000
soCuoi = 23100
soLuot = 8
Dim aL As Object
Set aL = CreateObject("System.Collections.ArrayList")
Dim i As Long
Randomize
For i = 1 To (soCuoi - soDau + 1) * soLuot[COLOR=#008000] ' lấy trị từ số đâu đến số cuối, n lần[/COLOR]
    aL.Add (Format(Rnd(), fmtRnd) & ((i - 1) Mod (soCuoi - soDau + 1)) + 1) [COLOR=#008000]' ghép sô ngẫu nhiên vào số mới lấy được[/COLOR]
Next i
aL.Sort
For i = 0 To aL.Count - 1
    [G1].Offset(i) = Val(Mid(aL(i), 9, 10)) + soDau - 1 [COLOR=#008000]' sửa [G1] để lấy ô theo ý[/COLOR]
Next i
Set aL = Nothing
End Sub
 
Web KT

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

Back
Top Bottom