Office中国论坛/Access中国论坛
标题: 如何随机不重复读取一个数组?? [打印本页]
作者: jiek 时间: 2002-12-29 19:20
标题: 如何随机不重复读取一个数组??
假设有一数组
dim x(1 to 100) as long
如何,随机的读取x(i) i>1 and i<100,且不要重复~
谢谢大家~
作者: Trynew 时间: 2002-12-29 20:53
读数前先洗一下“牌”。
dim j as integer, k as integer,temp as long
for j = 1 to 500 '洗牌次数
k=int(Rnd*100)+1
temp=x(1)
x(1)=x(k)
x(k)=Temp
Next
然后再取X(1)~X(i)就行了
作者: jiek 时间: 2002-12-30 07:48
斑竹,你好,谢谢你!
看了你的程序,还没有调试,有一点疑问?
1。随机数产生的k可能是相同的,那么同一x(k),就可以能赋给不同的x(i)?
2。循环500,是为了增大几率吗?x(1)到x(100)的是否都可以循环的到?
谢谢,帮忙回答一下拉~~~
作者: zhengjialon 时间: 2002-12-30 16:27
关注结果。
作者: tomzy 时间: 2002-12-30 16:57
提示: 作者被禁止或删除 内容自动屏蔽
作者: zhengjialon 时间: 2002-12-30 17:21
以下是引用jiek在2002-12-29 23:47:54的发言:
斑竹,你好,谢谢你!
看了你的程序,还没有调试,有一点疑问?
1。随机数产生的k可能是相同的,那么同一x(k),就可以能赋给不同的x(i)?
2。循环500,是为了增大几率吗?x(1)到x(100)的是否都可以循环的到?
谢谢,帮忙回答一下拉~~~
可以回答这些问题吗?谢谢!
作者: 李寻欢 时间: 2002-12-30 18:28
标题: 我个人认为单靠这几个变量,无法保证随机值不重复
如果要不重复地取值,要靠表来协助。所有的待选结果都放在一个表中,每个值都有一个是否已被选的标志字段,每次选取值的时候都查看该值是否被选中,如果是,就跳到下一记录。
我刚学Access时做过一个随机选题的例子,可以参考一下。
http://www.accxp.com/club/topic.cgi?forum=7&topic=202&show=400
作者: Trynew 时间: 2002-12-30 18:48
这个算法的原理是把数组X()里面的元素顺序调乱,没有取数也没有赋值,如果取两个随机数,以两个随机数为下标的数组元素互换效率会更高。就像一叠牌,每次从中间抽一张放到排顶,排顶的牌插入中间(或两牌互换位置),只要抽排的次数够多(循环500以上),牌就会均匀分布(洗牌过程),当然不保证是否都可以循环的到(有必要吗?)
执行完这个算法(洗牌过程)后,才是取数过程,按顺序取需要的个数或全部,像发牌一样。
这样的算法在要随机取给定数组的全部或大部分元素时比较适用。
当你不想打乱原数组的顺序时,可复制一个数组或给出一个维数相同的数列(象指针)进行处理。
作者: 李寻欢 时间: 2002-12-30 18:54
我也很想知道如何不用100个变量来做选取标志,而选取出100个不重复的数组值。
[此贴子已经被作者于2002-12-30 10:53:38编辑过]
作者: 李寻欢 时间: 2002-12-30 19:26
标题: 不重复读取一个数组,搞定!!
Private Sub 命令0_Click()
Dim a(1 To 100) As Long
Dim b(1 To 100) As Boolean
Dim i, j, k As Integer
'赋值给数组
i = 1
Do While i <= 100
a(i) = i
i = i + 1
Loop
'从数组随机读取值
For j = 1 To 100
k = Int(Rnd * 100) + 1
Do While b(k) = True
k = k + 1
If k > 100 Then k = 1
Loop
b(k) = True
Debug.Print a(k)
x = x + 1
DoEvents
Next j
End Sub
作者: Trynew 时间: 2002-12-30 22:00
不重复读取一个数组(用100个变量来做选取标志):
Public Sub ShowRnd()
'NumCount 为原始数组维数,SelCount 为随机数组维数
Const NumCount = 100, SelCount = 100
'NumAry 为原始数组,GetAry 为随机数组,selAry 数组存储已取过的数组下标
Dim NumAry(NumCount) As Long, GetAry(SelCount) As Long, selAry(SelCount) As Long
Dim i As Long, j As Long
'为原始数组赋值
For i = 1 To NumCount
NumAry(i - 1) = i * 10 '也可以赋其它值或字段值
Next
'为随机数组取值
For i = 0 To SelCount - 1
Do
selAry(i) = Int(Rnd() * NumCount) '取新下标
'逐个与已取过的数组下标比较
For j = 0 To i - 1
If selAry(i) = selAry(j) Then '重复取值
Exit For
End If
Next j
If j = i Then Exit Do '如果 j<i, 则重新执行循环,再取新下标
Loop
GetAry(i) = NumAry(selAry(i)) '用取得的新下标为随机数组赋值
if SelCount<100 then Debug.Print GetAry(i) '在调试窗口显示随机数组的值
Next i
Debug.Print "Finish" '随机数组取值完成
End Sub
'当数组较大,并且要(或接近)全部选取时,就不宜用这种方法,用表加标志不失为一个好办法,也可以用我给出的第一种算法(至少是稳定的,时间是固定的)。
作者: Trynew 时间: 2002-12-31 06:37
标题: 绝对最优算法!!!
由数组取部分(全部)不重复随机数组的算法:
[代码最简洁,变量最少,循环次数最少,有能改一字者,赏千金!!![em02]]
Private Sub 命令0_Click()
Const AllCount = 100, GetCount = 50
Dim a(1 To AllCount) As Long
Dim i, Temp, RndNum As Long
'赋值给数组
For i = 1 To AllCount
a(i) = i
Next
'给数组随机排序
For i = 1 To GetCount
RndNum = Int(Rnd * (AllCount + 1 - i)) + i '产生一个i到100之间的随机数
Temp = a(i)
a(i) = a(RndNum)
a(RndNum) = Temp
Debug.Print a(i)
Next i
End Sub
[此贴子已经被Trynew于2002-12-30 22:37:20编辑过]
欢迎光临 Office中国论坛/Access中国论坛 (http://www.office-cn.net/) |
Powered by Discuz! X3.3 |