生成不重复题目-随机

需求

答题系统,允许角色每天最多答对N道题目。 如果当天题库数量大于N,则要求当天答对的题目不能再出现。

糟糕的代码

以下是生成题目ID的实现大致如下,主要问题是作者没有想到很好的去重办法, 侥幸以为只要尽可能多的循环次数(2倍题库数量),来降低题目再次出现的概率,然而重复的题目还是出现了,这段糟糕的代码才“有幸”见于诸位。

lua代码

-- tQuestSave 记录当天答对题目
-- iQuestListSize  题库的数量
function GenQuestId(tQuestSave, iQuestListSize)
    local iTargetQuestId = -1
    for i = 1, iQuestListSize * 2, 1 do
        iTargetQuestId = math.random(1, iQuestListSize)
        if tQuestSave[iQuestId ] == nil then
             break
        end
    end
    return iTargetQuestId 
end

优化后

通过增大循环次数的随机做法,令算法非常不稳定。N个不重复的题目最终随机分散在题库里。N个题目彼此相邻是其中一种极端情况。 那么反过来想,在题库中随机在彼此相邻的N个题目中肯定有未答对的题目,算法的时间复杂度O(n)

lua代码

function GenQuestId(tQuestSave, iQuestSaveMaxSize, iQuestListSize)
    local iStartId= math.random(1, iQuestListSize)
    local iTargetQuestId = -1
    for i = 1, iQuestSaveMaxSize - 1, 1 do
         iTargetQuestId =  iStartId + i
        if tQuestSave[iTargetQuestId ] == nil then
             break
        end
    end
    return iTargetQuestId
end



原文:
https://lizijie.github.io/2021/07/17/%E7%94%9F%E6%88%90%E4%B8%8D%E9%87%8D%E5%A4%8D%E9%A2%98%E7%9B%AE-%E9%9A%8F%E6%9C%BA.html
作者github:
https://github.com/lizijie

PREVIOUSmmap相比于fwrite写日志,是否有性能优势?
NEXT生成赛事对阵图-洗牌