1
取一个包含 n 个元素的数组:{ 1, 2, 3, .... n }。使用任意随机洗牌数组的标准算法对数组进行洗牌。修改后的数组的前 N 个元素就是您要查找的内容。
2
只需使用Random.Next()
循环并检查它是否已经存在于Dictionary
,直到我们有 N 个数字。
请注意,N
这些都不是最好的。你需要费舍尔-耶茨洗牌。随机解决方案的问题在于您预先做了很多不必要的工作。第二种解决方案的问题在于,随着时间的推移,重复的可能性会变得更高,因此您会丢弃很多值。
一个非常有效的解决方案,为您提供您的价值观的子集zero重复的可能性(并且没有不必要的预先排序),Fisher-Yates 是最佳选择。
dim n[N] // gives n[0] through n[N-1]
for each i in 0..N-1:
n[i] = i // initialise them to their indexes
nsize = N // starting pool size
do N times:
i = rnd(nsize) // give a number between 0 and nsize-1
print n[i]
nsize = nsize - 1 // these two lines effectively remove the used number
n[i] = n[nsize]
只需从池中选择一个随机数,将其替换为该池中的顶部数字,然后减小池的大小,您就可以进行洗牌,而不必担心预先进行大量交换。
如果数字很大,这一点很重要,因为它不会引入不必要的启动延迟。
例如,检查以下基准检查,从 10 中选择 10:
<------ n[] ------>
0 1 2 3 4 5 6 7 8 9 nsize rnd(nsize) output
------------------- ----- ---------- ------
0 1 2 3 4 5 6 7 8 9 10 4 4
0 1 2 3 9 5 6 7 8 9 7 7
0 1 2 3 9 5 6 8 8 2 2
0 1 8 3 9 5 6 7 6 6
0 1 8 3 9 5 6 0 0
5 1 8 3 9 5 2 8
5 1 9 3 4 1 1
5 3 9 3 0 5
9 3 2 1 3
9 1 0 9
您可以看到池随着您的使用而减少,并且因为您总是用未使用的替换旧的,所以您永远不会重复。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)