Lua 中如何进行 Fisher-Yates 洗牌

Zac*_*yCW 5 random lua shuffle

我一直在询问有关随机数的问题,我认为费舍尔-耶茨洗牌将是最好的选择。我做了一张桌子“t”

t = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Run Code Online (Sandbox Code Playgroud)

现在,我如何重新排列这些并能够单独使用它们,例如在另一个表中生成结果u

u = {}
Run Code Online (Sandbox Code Playgroud)

MHe*_*bes 7

对于那些稍后找到这个答案的人,这将在适当的位置进行洗牌,而无需创建新表:

local function ShuffleInPlace(t)
    for i = #t, 2, -1 do
        local j = math.random(i)
        t[i], t[j] = t[j], t[i]
    end
end
Run Code Online (Sandbox Code Playgroud)

这个返回一个打乱的表而不触及原始表(与当前答案不同,它既就地打乱并返回一个副本):

local function Shuffle(t)
    local s = {}
    for i = 1, #t do s[i] = t[i] end
    for i = #t, 2, -1 do
        local j = math.random(i)
        s[i], s[j] = s[j], s[i]
    end
    return s
end
Run Code Online (Sandbox Code Playgroud)

用法:

local t = {"a", "b", "c", "d", "e", "f"}

print(table.concat(t)) --> abcdef
    
local s = Shuffle(t)
    
print(table.concat(t)) --> abcdef (unchanged)
print(table.concat(s)) --> fbcade (shuffled)

ShuffleInPlace(t)
    
print(table.concat(t)) --> dcbfea (shuffled)
Run Code Online (Sandbox Code Playgroud)

并快速检查它们是否一致:

local t = {"a", "b", "c", "d", "e", "f"}

print(table.concat(t)) --> abcdef
    
local s = Shuffle(t)
    
print(table.concat(t)) --> abcdef (unchanged)
print(table.concat(s)) --> fbcade (shuffled)

ShuffleInPlace(t)
    
print(table.concat(t)) --> dcbfea (shuffled)
Run Code Online (Sandbox Code Playgroud)

  • 这个答案更有帮助和准确+1,已接受的答案有很多问题,感谢您修复它们。 (2认同)

hjp*_*r92 3

注意:检查其他答案/sf/answers/4794039351/,它修复了下面代码片段中的问题并提供了其他替代方案

如果您的桌子上没有洞:

math.randomseed(os.time()) -- so that the results are always different
function FYShuffle( tInput )
    local tReturn = {}
    for i = #tInput, 1, -1 do
        local j = math.random(i)
        tInput[i], tInput[j] = tInput[j], tInput[i]
        table.insert(tReturn, tInput[i])
    end
    return tReturn
end
Run Code Online (Sandbox Code Playgroud)

  • 我的问题是,我该如何使用这个?假设 t = {A, B, C, D, E},我怎样才能打印出像“C, D, E, B, A”这样的东西?随机在哪里? (2认同)