我正在尝试创建一个生成随机数的函数,但绝不会两次。
这是我到目前为止所得到的,但它不起作用。它编译,但然后再次在我的数组中插入相同数字的多次。
quiz = 10
array = {}
array[1] = 0 -- just to have something in it because it won't work in my loop otherwise...
ok = false
repeat
rdm = math.ceil(math.random() * quiz)
for i = 0, #array do
if(rdm == array[i]) then
break -- to break the for loop to pick a new number
elseif(rdm ~= array[i]) then
ok = true -- to end the repeat loop
table.insert(array, rdm) -- to keep a track of what I got so far
end
end
until ok == true
for b = 0, #array do -- #array should be ten
print(array[b])
end
它的作用是生成相同数字的多倍,并表示它与表格中的数字不同...
我想我的问题来自逻辑......但我不知道它对我来说有什么意义
答案 0 :(得分:2)
如果您知道最多需要N个数字,则可以预生成随机数并根据其值将其插入表中。然后你的函数从该表中随机选取一个数字并删除该数字。类似的东西:
local rands = {}
local numRands = 100
-- populate table of random numbers
while #rands < numRands do
local r = math.random(1,1000)
rands[r]=r -- if duplicate, table stays same
end
local function getNeverSameRandom()
local index = math.random(1,numRands)
return table.remove(rands, index)
end
如果您不知道要填充多少,请通过表格跟踪:
local randsUsed = {}
local maxRand = 1000000 -- largest random # you want
local function getNeverSameRandom()
local rnd
repeat
rnd = math.random(1,maxRand)
until randsUsed[rnd] == nil
randsUsed[rnd] = rnd
return rnd
end
问题当然是如果你多次调用getNeverSameRandom,比如最大随机数的一半,你的randsUsed表将会变得非常充实,而repeat-until将需要更长时间。最终,表格将满,并且该函数将处于无限循环中。您可以通过跟踪计数器轻松检查,但不能使用#randsUsed
,因为randsUsed
是一个带有“洞”的表,因此无法使用#操作。例如:
local randsUsedCount = 0
local function getNeverSameRandom()
if randsUsedCount == maxRand then
error("No more random #'s left in range 1-"..maxRand)
end
local rnd
repeat
rnd = math.random(1,maxRand)
until randsUsed[rnd] == nil
randsUsed[rnd] = rnd
randsUsedCount = randsUsedCount + 1
return rnd
end
答案 1 :(得分:2)
最简单的方法是使用您需要的序列预填充元素数组(例如,1..1000),然后使用Fisher-Yates algorithm之类的内容对元素进行洗牌:
local rands, n = {}, 1000
-- prepopulate
for i = 1, n do rands[i] = i end
-- shuffle
for i = n, 2, -1 do
local j = math.random(i)
rands[j], rands[i] = rands[i], rands[j]
end
-- use
print(table.remove(rands))
同一页面也有进行初始化和改组的算法的“由内而外”版本。