vb/vba抽取不重复随机数

  • 发布时间:2016年7月13日 09:00
  • 作者:杨仕航
  • 分类标签: vb/vba
  • 阅读(16393)
  • 评论(0)

vb/vba 抽取随机数可以用Rnd函数,但它只是一个最基本最简单的随机函数,结果是0到1之间的小数。若要限定范围,限定小数位数,还需要写其他代码控制。例如要抽取1到100的随机整数数,代码如下:

int(Rnd()*99) + 1

Rnd函数得到的结果是0到1,乘以99就得到0到99范围的数。再用int函数取整和加上1,就可以得到1到100范围内的随机整数。

这样,我就可以反复利用这句代码得到多个1到100之间的随机整数。但这些随机数可能会重复。

若我们想在1到100之间抽取10个不重复的随机整数。这句代码就实现不了,得另寻他路。


这里可以采用数组法。因为数组有两个值:一个是数组下标;一个是数组的值。

这样我们可以对数组下标进行随机抽取。每次抽取之后的值拿出来,再调整数组下标要抽取的范围。这样就可以实现不重复抽取随机数。


举个例子,现有数字1到6,要不重复随机抽取3个数字。

将其放在1个数组中,进行第1次抽取。如下图:

按照这种方法,继续第2次抽取随机数,再把抽取出来的值调整到前面。如下图:

也有可能抽取的随机数刚好在其范围的第1位,无需交换。第3次抽取,如下图:

这样就可以获取该数组的前3个元素。这3个元素就是不重复的随机抽取结果。

根据这个思路,写了一个函数(这个已经可以归为是算法了),代码如下:

'作者:杨仕航'
'抽取不重复随机数函数'
'参数1:arr,数组,抽取随机数的样本(数据源)'
'参数2:lngNum,长整数,要抽取的个数'
Public Function RndSample(arr(), lngNum As Long)
    '判断要获取的个数'
    Dim lngLength As Long
    lngLength = UBound(arr) - LBound(arr) + 1     '获取长度'

    '若要获取随机数的个数大于等于数组长度,直接返回整个数组'
    If lngNum >= lngLength Then
        RndSample = arr
        Exit Function
    End If

    '随机数的个数不能少于1个'
    If lngNum < 1 Then lngNum = 1

    '抽取随机数'
    Randomize               '重置随机器'
    Dim lngRnd As Long      '用于存在返回的随机数'
    Dim varTemp As Variant  '两个变量调换的中间临时变量'
    Dim lngTimes As Long    '记录第几次抽取'
    lngTimes = 1
    
    Do
        '抽取lngTimes-1 ~ lngLength范围的随机数'
        lngRnd = Int(Rnd() * (lngLength - lngTimes)) + lngTimes - 1

        '调换值,将抽取到的随机数下标对应的值放到前面'
        '之所以放到前面,是为了方便返回结果'
        varTemp = arr(lngTimes - 1)
        arr(lngTimes - 1) = arr(lngRnd)
        arr(lngRnd) = varTemp

        '继续抽取'
        lngTimes = lngTimes + 1
    Loop While lngTimes <= lngNum

    '返回结果,截取抽取的随机数个数,Preserve 关键字作用是ReDim重新定义不清除值'
    ReDim Preserve arr(lngNum - 1)
    RndSample = arr
End Function


再写个测试代码:

Public Sub test()
    Dim arr(), re()
    'arr = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)'
    arr = Array("A", "B", "C", "D", "E")
    re = RndSample(arr, 3)
    
    Dim i As Long
    For i = 0 To UBound(re)
        Debug.Print re(i)
    Next
End Sub

给RndSample函数,传递两个参数,第一个是抽取随机数的样本(数据源)数组,第二个参数是要抽取的个数。

该数组可以是纯数字,也可以是文本,也可以是数字和文本混搭。

测试通过,可以得到不重复随机数 ^_^ (还是Python好,可以用Random模块中的Sample方法直接得到不重复的随机数)

上一篇:树莓派控制LED闪烁和呼吸

下一篇:Python多线程使用win32com注意事项

评论列表

智慧如你,不想发表一下意见吗?

新的评论

清空