如何随机生成N个数字?

yomiko 2004-05-06 07:14:14
比如随机生成10个数字,数字可以相同(随便请教如果要求10个数都不相同,又该如何做?)
...全文
242 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
KiteGirl 2004-05-07
  • 打赏
  • 举报
回复
哈哈!“动态跳蚤”算法完成!可以取Long规定范围的任意值。内存空间与取得随机不重复序列的数量关系(但不是直线关系)。

测试代码:(测试中只用了大约20个元素)

Private Sub Command2_Click()
Dim tLongs() As Long
tLongs() = RandomArrayGet(10, -10000, 10000)

For tIndex = 0 To UBound(tLongs)
Text2.Text = Text2.Text & " " & tLongs(tIndex)
Next
End Sub

模块:

Type tpActiveArray_Element
aaIndex As Long
aaValue As Long
End Type

Function RandomArrayGet(ByVal pOutCount As Long, ByVal pValueMin As Long, ByVal pValueMax As Long) As Long()
Dim tOutLongs() As Long

Dim tSurArray() As tpActiveArray_Element
Dim tSurArrayBacks() As tpActiveArray_Element

Dim tSwapIndex As Long
Dim tIndex As Long
Dim tValueLength As Long

tValueLength = (pValueMax - pValueMin) + 1

For tIndex = 0 To pOutCount - 1
tSwapIndex = Int(Rnd * tValueLength)
If Not CBool(DummyActiveArray_ValueGetByIndex(tSurArrayBacks(), tIndex)) Then
DummyActiveArray_ValuePutToIndex tSurArrayBacks(), tIndex, -1
DummyActiveArray_ValuePutToIndex tSurArray(), tIndex, tIndex
End If
If Not CBool(DummyActiveArray_ValueGetByIndex(tSurArrayBacks(), tSwapIndex)) Then
DummyActiveArray_ValuePutToIndex tSurArrayBacks(), tSwapIndex, -1
DummyActiveArray_ValuePutToIndex tSurArray(), tSwapIndex, tSwapIndex
End If
DummyActiveArray_ValueSwap tSurArray(), tIndex, tSwapIndex
DummyActiveArray_ValueSwap tSurArrayBacks(), tIndex, tSwapIndex
Next

ReDim tOutLongs(pOutCount - 1)

For tIndex = 0 To pOutCount - 1
tOutLongs(tIndex) = DummyActiveArray_ValueGetByIndex(tSurArray(), tIndex) + pValueMin
Next

Form1.Text1.Text = UBound(tSurArray)

RandomArrayGet = tOutLongs()

End Function

Sub DummyActiveArray_ValueSwap(ByRef pArray() As tpActiveArray_Element, ByVal pDummyIndexA As Long, ByVal pDummyIndexB As Long)
Dim tTempElement As tpActiveArray_Element
Dim tElementA_RealIndex As Long
Dim tElementB_RealIndex As Long

tElementA_RealIndex = RealActiveArray_IndexGetByDummyIndex(pArray(), pDummyIndexA)
tElementB_RealIndex = RealActiveArray_IndexGetByDummyIndex(pArray(), pDummyIndexB)

tTempElement.aaValue = pArray(tElementA_RealIndex).aaValue
pArray(tElementA_RealIndex).aaValue = pArray(tElementB_RealIndex).aaValue
pArray(tElementB_RealIndex).aaValue = tTempElement.aaValue

End Sub

Function DummyActiveArray_ValueGetByIndex(ByRef pArray() As tpActiveArray_Element, ByVal pDummyIndex As Long) As Long
'从ActiveArray获得一个虚拟索引对应的元素值
Dim tOutLong As Long

Dim tIndex As Long

tIndex = RealActiveArray_IndexGetByDummyIndex(pArray(), pDummyIndex)
tOutLong = pArray(tIndex).aaValue

DummyActiveArray_ValueGetByIndex = tOutLong
End Function

Sub DummyActiveArray_ValuePutToIndex(ByRef pArray() As tpActiveArray_Element, ByVal pDummyIndex As Long, ByVal pValue As Long)
'将一个值写入ActiveArray对应虚拟索引的元素

Dim tOutLong As Long

Dim tIndex As Long

tIndex = RealActiveArray_IndexGetByDummyIndex(pArray(), pDummyIndex)
pArray(tIndex).aaValue = pValue

End Sub

Function RealActiveArray_IndexGetByDummyIndex(ByRef pArray() As tpActiveArray_Element, ByRef pDummyIndex As Long) As Long
'返回一个虚拟索引对应的元素在一个ActiveArray的真实索引。如果虚拟索引对应的元素不存在,则创建一个。
Dim tOutIndex As Long

Dim tArray_Count As Long
Dim tArray_Index As Long

tOutIndex = -1

tArray_Count = RealActiveArray_Count(pArray())

If CBool(tArray_Count) Then
For tIndex = 0 To tArray_Count - 1
With pArray(tIndex)
If .aaIndex = pDummyIndex Then
tOutIndex = tIndex
Exit For
End If
End With
Next
Else
End If

If tOutIndex < 0 Then
ReDim Preserve pArray(tArray_Count)
With pArray(tArray_Count)
.aaIndex = pDummyIndex
End With
tOutIndex = tArray_Count
End If

RealActiveArray_IndexGetByDummyIndex = tOutIndex
End Function

Function RealActiveArray_Count(ByRef pArray() As tpActiveArray_Element) As Long
'获得一个ActiveArray的真实元素数量。
Dim tOutLong As Long

Err.Clear
On Error Resume Next

tOutLong = UBound(pArray()) + 1

RealActiveArray_Count = tOutLong
End Function
KiteGirl 2004-05-07
  • 打赏
  • 举报
回复
暂时完成“虚拟数组”部分。基于“虚拟数组”的“热跳蚤算法”稍后完成。

演示代码:
Private Sub Command1_Click()
Dim tArray() As tpActiveArray_Element
Dim tIndex As Long
For I = 0 To 100
tIndex = Int(Rnd * 2 ^ 16)
DummyActiveArray_ValuePutToIndex tArray(), tIndex, Int(Rnd * 2 ^ 16)
Next
Text1.Text = UBound(tArray)
End Sub

虚拟数组模块:

Type tpActiveArray_Element
aaIndex As Long
aaValue As Long
End Type

Function DummyActiveArray_ValueGetByIndex(ByRef pArray() As tpActiveArray_Element, ByVal pDummyIndex As Long) As Long
'从ActiveArray获得一个虚拟索引对应的元素值
Dim tOutLong As Long

Dim tIndex As Long

tIndex = RealActiveArray_IndexGetByDummyIndex(pArray(), pDummyIndex)
tOutLong = pArray(tIndex).aaValue

DummyActiveArray_ValueGetByIndex = tOutLong
End Function

Sub DummyActiveArray_ValuePutToIndex(ByRef pArray() As tpActiveArray_Element, ByVal pDummyIndex As Long, ByVal pValue As Long)
'将一个值写入ActiveArray对应虚拟索引的元素

Dim tOutLong As Long

Dim tIndex As Long

tIndex = RealActiveArray_IndexGetByDummyIndex(pArray(), pDummyIndex)
pArray(tIndex).aaValue = pValue

End Sub

Function RealActiveArray_IndexGetByDummyIndex(ByRef pArray() As tpActiveArray_Element, ByRef pDummyIndex As Long) As Long
'返回一个虚拟索引对应的元素在一个ActiveArray的真实索引。如果虚拟索引对应的元素不存在,则创建一个。
Dim tOutIndex As Long

Dim tArray_Count As Long
Dim tArray_Index As Long

tOutIndex = -1

tArray_Count = RealActiveArray_Count(pArray())

If CBool(tArray_Count) Then
For tIndex = 0 To tArray_Index
With pArray(tIndex)
If .aaIndex = pDummyIndex Then
tOutIndex = tIndex
Exit For
End If
End With
Next
Else
End If

If tOutIndex < 0 Then
ReDim Preserve pArray(tArray_Count)
With pArray(tArray_Count)
.aaIndex = pDummyIndex
End With
tOutIndex = tArray_Count
End If

RealActiveArray_IndexGetByDummyIndex = tOutIndex
End Function

Function RealActiveArray_Count(ByRef pArray() As tpActiveArray_Element) As Long
'获得一个ActiveArray的真实元素数量。
Dim tOutLong As Long

Err.Clear
On Error Resume Next

tOutLong = UBound(pArray()) + 1

RealActiveArray_Count = tOutLong
End Function
pigpag 2004-05-06
  • 打赏
  • 举报
回复
//该法缺点是有一个检索元素过程

是啊,看看复杂度,从O(N)立刻跳到O(N2)
KiteGirl 2004-05-06
  • 打赏
  • 举报
回复
最近正在研究一种跳蚤算法的改型,该算法可以解决内存空间占用问题和初始化数组的时间问题。基本原理是:

1、以一种“虚拟数组”代替真实的数组,只有用到的元素才占用内存空间。该法缺点是有一个检索元素过程,不如真实数组迅速。

2、将数组初始化过程在交换过程中动态完成。
pigpag 2004-05-06
  • 打赏
  • 举报
回复
小仙妹的跳蚤算法的根本缺陷是内存占用问题。所以遇到随机待选样本空间很大的情况就没办法了。(觉得此算法有点浪费内存,不过资源和速度是一对矛盾,呵呵)
KiteGirl 2004-05-06
  • 打赏
  • 举报
回复
不重复随机数可以用我的看家本领“跳蚤算法”,前提是这个随机数的取值是确定,并且范围不大的。

其原理是这样的:
1、建立一个数组,该数组的大小取决于取随机不重复序列的最大值。比如你要取0-100之间的数字,则需要建立101个元素(0-100)的数组。

2、为数组的每个元素设置初始值,初始值就是该元素的索引。

3、将前N个元素与第R个元素交换。0<=N<=元素的数量。R为随机数,0<=R<=元素的数量

4、前N个元素就是随机不重复序列。

该算法是我根据用彩球取彩票号码的情景构思出来的。由于工作的时候,每个元素的值好象跳蚤一样到处转移,因此叫做“跳蚤算法”。学名似乎应该叫“有限序列交换法”比较恰当。
该算法的优点是在时间上比较迅速稳定。
该算法的缺点主要是:数组的绝对差不能太大。比如:你要在0-1000000000000之间取N个不重复序列、或者取0.000000000001-0.1之间的小数。该算法就难以满足了。但1000000000000-1000000010000之间的整数、位数比较少的小数还是可以的。(小数采用乘法放大)

取12个0-99以内的随机不重复正整数序列:

Dim tNumbers() As Long
Dim tMax As Long
Dim tIndex As Long
Dim tSwapIndex As Long
Dim tT As Long

tMax=99

ReDim tNumbers(tMax)

For tIndex=0 To 99
tNumbers(tIndex)=tIndex
Next

For tIndex=0 To 11
tSwapIndex=Int(Rnd*(tMax+1))'确定交换目标
'将当前元素与随机元素交换。
tT=tNumbers(tIndex)
tNumbers(tIndex)=tNumbers(tSwapIndex)
tNumbers(tSwapIndex)=tT
Next

tNumbers()的0-11这12个元素必然是随机不重复序列。
Mi_Bo 2004-05-06
  • 打赏
  • 举报
回复
生成n1——n2之间的整数的方法是:int(rnd*(n2-n1+1))
pigpag 2004-05-06
  • 打赏
  • 举报
回复
用Collection更方便

Dim C As New Collection, I As Integer

On Error Resume Next
Do Until C.Count = 个数
I = Int(Rnd(1)*(上限-下限+1)+下限)
C.Add I, CStr(I)
Loop

当然,如果个数<上限-下限+1,就会死循环

不过这段代码就图个简单,效率很低。个数大的时候不推荐使用。
broown 2004-05-06
  • 打赏
  • 举报
回复
Dim MyValue
MyValue = Int((6 * Rnd) + 1) ' 生成 1 到 6 之间的随机数值。

lk_cool 2004-05-06
  • 打赏
  • 举报
回复
以前别人的算法:

'生成52个1到100的不重复随机数

'=============================
Dim i, j As Long
Dim ran(1 To 52) As Long
Dim tNum As Long
Dim isExist As Boolean
Randomize

For i = 1 To 52
isExist = False
tNum = Int(100 * Rnd + 1)
Debug.Print tNum
For j = 1 To i
If ran(j) = tNum Then
isExist = True
i = i - 1
Exit For
End If
Next
If isExist = False Then
ran(i) = tNum
End If
Next

For i = 1 To 52
msg = msg & ran(i) & Space(1)
Next
MsgBox msg
liyufeng1983 2004-05-06
  • 打赏
  • 举报
回复
当然用随机函数了random()

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧