lua洗牌和發紅包算法

--Fisher-Yates Shuffle
--洗牌算法,用於將一組數據等概率隨機打亂。等概率算法。
local function shuffle(t)
    if not t then return end
    local cnt = #t
    for i=1,cnt do
        local j = math.random(i,cnt)
        t[i],t[j] = t[j],t[i]
    end
end

--分紅包算法
local function split(m,n)
    --構造m-1個可用的分割標記位
    local mark = {}
    for i=1,m-1 do
        mark[i] = i
    end

    --打亂標所有記位
    shuffle(mark)
    --構建一個新的表,並從mark表中取前n-1個位置作爲有效標記位
    local validMark = {}
    for i=1,n-1 do
        validMark[i] = mark[i]
    end

    --重新按從小到大排序有效標記
    table.sort(validMark,function (a,b)
        return a<b
    end)

    --設置有效標記表的頭、尾分別爲0和m
    validMark[0] = 0
    validMark[n] = m
    --構建輸出數組
    local out = {}
    for i=1,n do
        out[i] = validMark[i] - validMark[i-1]
    end
    return out
end

local function main()
    --設置隨機數種子
    math.randomseed(tostring(os.time()):reverse():sub(1,6))
    local M = 10000
    local N = 100
    local data = split(M,N)

    -- 輸出結果,並驗算一下紅包總錢數
    local datasum = 0
    local outstr = ""
    for i=1,N do
        datasum = data[i] + datasum
        outstr = outstr .. data[i] .. ((0 == i%10) and "\n" or "\t")
    end

    print ("datasum = " .. datasum)
    print (outstr)
end

main()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章