VB生成不重复的随机数
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VB生成不重复的随机数
我的建议是:第一步、先做一个数组,存上这35个数(可以不是连续的数,也可以是人名、字符串什么的);第二步、随机生成一个1-35之间的数,输出;第三步:把这个数和数组的第一个单元交换;第四步、从数组的第2-35之间随机抽取第二个数,输出;第五步、把这随机抽取的第二个数和数组的第二个单元内容呼唤;第六步、随机抽取第三个数,输出。。。。。重复到从第35-35个数之间随机抽取一个数,这时直接输出最后一个就行了。
程序如下(VB6):
工程里默认的窗体上,画一个Command1,粘贴程序:
option explicit
private vArray(1 to 35) as currency '定义数组个数
private sub command1_click()
test
end sub
private sub InitArray()
dim i as long
'给数组赋值
for i=1 to 35
varray(i)=i
next i
end sub
private sub Test()
dim iStart as long
dim iPos as long
dim vTemp as currency
dim sReturn as string
InitArray
randomize timer '设置随机因子,使其每次运行程序的随机数都不一样
iStart=1
do
iPos=int(rnd*(ubound(vArray)-iStart+1))+iStart '产生iStart到35(35取自vArray的上标)之间的整数
sReturn=sReturn & vArray(iPos) & vbcrlf '输出
'交换单元内容
vTemp=vArray(iStart)
vArray(iStart)=vArray(iPos)
vArray(iPos)=vTemp
iStart=iStart+1 '下次随机生成时,少生成一个
if iStart>=ubound(vArray) then
'最后一个了,直接输出
sReturn=sReturn & vArray(ubound(vArray))
Exit Do
end if
if iStart>7 then exit do '如果需要生成几个数,就把7改成几,大于数组元素的个数,将输出速度的元素个数(这个例子是35)
Loop
msgbox sReturn 'msgbox 输出结果
end sub
'==============================================================================================
'方法二
Private Sub Command1_Click()
Dim a(35) As Integer
For i = 0 To 35
way1:
Randomize
a(i) = Int(Rnd() * 36) + 1
If i > 1 Then
For p = 0 To i - 1
If a(p) = a(i) Then '‘与前面的对比,如果有重复,重新随机
GoTo way1
End If
Next p
End If
Print a(i); '打印
Next i
Print "" '打印
End Sub
'==========================================================================================
'方法三
如果楼主是要产生0-9等10个不重复的随机数的话,在随机数范围和个数相等的情况下,楼上的方法都无异于散弹打鸟。在最不利情况下时间将无限延长,特别是对更多随机数的时候。
以下提供两种思路:
1.实际上我们只要确定了其中9个数字那么第10个数字根本不用去想;
确定8个,那么随机只在2个数之间,以此类推,使用动态数组如a(),先用for将10个数字加入,然后开始rnd*ubound(a)取得其中一个,放入数组b,再将该数字从a数组中剔除。速度:(n+n^2)/2
2.只需要得到10个无序排列的数字即可,没必要去一直产生随机数,只要打乱顺序即可。在数组a中加入10个数字,然后开始for循环10次,每次产生一个10以内的随机数,然后将循环次数i与随机数的位置互换。速度:n
'================================================================================================
'方法四
关于随机数的不重复求取
Option Base 1
Private Sub Command1_Click()
Randomize Timer
Dim A(1 To 10) As Integer '数组M
Dim B(1 To 8) As String '数组N
Dim i As Integer, k As Integer, t As Integer
For i = 1 To 10
A(i) = i
Next
For i = 1 To 10 '数组打乱
t = A(i)
k = Fix(Rnd * 10) + 1
A(i) = A(k)
A(k) = t
Next
For i = 1 To 8 '从M中随机取出N个数,不重复
B(i) = A(i)
Next
Label1.Caption = Join(B(), " , ")
End Sub
'方法五======================================================
Private Sub Command2_Click()
Randomize Timer
Dim Dimension(8)
Dim i As Byte, j As Byte
Randomize Timer
For i = 1 To 8
Dimension(i) = Fix(Rnd * 10) + 1
Next i
A: For i = 1 To 7
For j = i + 1 To 8
If Dimension(i) = Dimension(j) Then
Dimension(i) = Fix(Rnd * 10) + 1
GoTo A
End If
Next j
Next i
Label1.Caption = Join(Dimension(), " , ")
End Sub
Private Sub Command3_Click()
End
End Sub
'===============================================================
'方法六:(最快)
还有种方法是随机取数组中一个数,取出后将该元素与数组最后一个元素交换,然后随机上限减一
然后就是字符串的速度了...一次分配足够大的字符串,而不是用&连接字符串会快很多
Option Explicit
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Const MAX_N = 10000 - 1 '在1~(MAX_N+1)的数字中取
Private Sub Command1_Click()
Dim Ary(MAX_N) As Long
Dim i&, n&, p&, t&, ps&
Dim s$, sTemp$
t = timeGetTime
'初始化
For i = 0 To MAX_N
Ary(i) = i + 1
Next
Randomize
' '计算并为s分配足够的大小,下面是当n=MAX_N+1时最终的s的长度的精确值
' i = MAX_N + 1: p = 0: ps = 9
' Do Until i <= 9
' p = p + 1
' n = n + ps * p
' ps = ps * 10
' i = i \ 10
' Loop
' n = n + (p + 1) * (MAX_N - CLng(10 ^ p) + 2) + MAX_N
' s = String$(n, ",")
n = MAX_N \ 2 '要取的个数,取所有的话用MAX_N+1
'计算并为s分配足够的大小
s =
String$(n * Len(CStr(MAX_N + 1)), ",") '分配足够大的内存,以后再减
p = 0: ps = 1
Do Until p >= n
i = CLng(Rnd * (MAX_N - p))
sTemp = CStr(Ary(i))
Mid$(s, ps, Len(sTemp)) = sTemp
ps = ps + Len(sTemp) + 1
Ary(i) = Ary(MAX_N - p) '如果不想破坏数据,把这里改成2个元素交换,而不是简单赋值
p = p + 1 '抛弃数组最后一个元素
Loop
s = Left$(s, ps - 2) '去掉多余的部分
t = timeGetTime - t
Debug.Print s '输出
Debug.Print CStr(t), Len(s)
End Sub
'===============================================================
'方法七:(最快)
Option Explicit
Option Base 1
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Const Nums = 10000
Private Sub Command1_Click()
Dim t As Long
Dim Num(Nums) As Long
Dim i, n As Long
Dim s As String
t = timeGetTime
Randomize
For i = 1 To Nums
n = Int(Rnd * Nums) + 1
If Num(n) = 0 Then
Num(n) = n
s = s & n & ","
Else
i = i - 1
End If
Next i
Text1.Text = s
t = timeGetTime - t
MsgBox t
End Sub