Lua版組合算法


高效率的排列組合算法--《編程珠磯》--Lua實現

原文鏈接

原文是python實現的,這里給出lua版本的實現

 

組合算法   
  本程序的思路是開一個數組,其下標表示1到m個數,數組元素的值為1表示其下標  
  代表的數被選中,為0則沒選中。     
  首先初始化,將數組前n個元素置1,表示第一個組合為前n個數。     
  然后從左到右掃描數組元素值的“10”組合,找到第一個“10”組合后將其變為   
  “01”組合,同時將其左邊的所有“1”全部移動到數組的最左端。     
  當第一個“1”移動到數組的m-n的位置,即n個“1”全部移動到最右端時,就得   
  到了最后一個組合。     
  例如求5中選3的組合:     
  1   1   1   0   0   //1,2,3     
  1   1   0   1   0   //1,2,4     
  1   0   1   1   0   //1,3,4     
  0   1   1   1   0   //2,3,4     
  1   1   0   0   1   //1,2,5     
  1   0   1   0   1   //1,3,5     
  0   1   1   0   1   //2,3,5     
  1   0   0   1   1   //1,4,5     
  0   1   0   1   1   //2,4,5     
  0   0   1   1   1   //3,4,5  

-- 從長度為m的數組中選n個元素的組合
function comm.zuhe(atable, n)
    if n > #atable then
        return {}
    end

    local len = #atable
    local meta = {}
    -- init meta data
    for i=1, len do
        if i <= n then
            table.insert(meta, 1)
        else
            table.insert(meta, 0)
        end
    end

    local result = {}

    -- 記錄一次組合
    local tmp = {}
    for i=1, len do
        if meta[i] == 1 then
            table.insert(tmp, atable[i])
        end
    end
    table.insert(result, tmp)

    while true do
        -- 前面連續的0
        local zero_count = 0
        for i=1, len-n do
            if meta[i] == 0 then
                zero_count = zero_count + 1
            else
                break
            end
        end
        -- 前m-n位都是0,說明處理結束
        if zero_count == len-n then
            break
        end

        local idx
        for j=1, len-1 do
            -- 10 交換為 01
            if meta[j]==1 and meta[j+1] == 0 then
                meta[j], meta[j+1] = meta[j+1], meta[j]
                idx = j
                break
            end
        end
        -- 將idx左邊所有的1移到最左邊
        local k = idx-1
        local count = 0
        while count <= k do
            for i=k, 2, -1 do
                if meta[i] == 1 then
                    meta[i], meta[i-1] = meta[i-1], meta[i]
                end
            end
            count = count + 1
        end

        -- 記錄一次組合
        local tmp = {}
        for i=1, len do
            if meta[i] == 1 then
                table.insert(tmp, atable[i])
            end
        end
        table.insert(result, tmp)
    end

    return result
end

 

算法是經過優化的版本,效率還算可以,感興趣的可以自己跑一下測試!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM