如何在Lua中制作一个函数,从不重复选取相同的数字
2018-3-11 5:34:17
收藏:0
阅读:84
评论:2
我正在尝试编写一个生成随机数字但不重复的函数。
这是我目前的代码,但它不起作用。它可以编译,但在数组中多次插入相同的数字。
quiz = 10
array = {}
array[1] = 0 -- 只是为了有一个东西在里面,否则我的循环就不起作用了...
ok = false
repeat
rdm = math.ceil(math.random() * quiz)
for i = 0, #array do
if(rdm == array[i]) then
break -- 打破 for 循环以选择一个新数字
elseif(rdm ~= array[i]) then
ok = true -- 结束 repeat 循环
table.insert(array, rdm) -- 记录到目前为止所获得的内容
end
end
until ok == true
for b = 0, #array do -- #array 应该是十
print(array[b])
end
它会生成多次相同的数字,并说它与表中的数字不同...
我想我的问题来自于逻辑...但我不知道从哪里来,因为对我来说它都是有意义的。
点赞
用户1442917
最简单的方法可能是预先填充一个元素数组,使用您需要的序列(例如,1..1000),然后使用类似Fisher-Yates 算法的方法就地洗牌:
local rands, n = {}, 1000
-- 预先填充
for i = 1, n do rands[i] = i end
-- 洗牌
for i = n, 2, -1 do
local j = math.random(i)
rands[j], rands[i] = rands[i], rands[j]
end
-- 使用
print(table.remove(rands))
同样的页面还有“inside-out”版本算法,可以完成初始化和洗牌两个步骤。
2014-02-22 06:55:23
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
如果你知道你需要的随机数最多是 N 个,你可以预先生成随机数并将它们按值插入到表中。然后你的函数从表中随机选择一个数并删除它。代码如下:
local rands = {} local numRands = 100 -- populate table of random numbers while #rands < numRands do local r = math.random(1,1000) rands[r]=r -- 如果有重复,表格中保持不变 end local function getNeverSameRandom() local index = math.random(1,numRands) return table.remove(rands, index) end如果您不知道需要填充的数量,则通过表跟踪:
local randsUsed = {} local maxRand = 1000000 -- 您想要的最大随机数 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