zoukankan      html  css  js  c++  java
  • 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

    算法是经过优化的版本,效率还算可以,感兴趣的可以自己跑一下测试!

  • 相关阅读:
    linux svn切换用户
    解决QQ“抱歉,无法发起临时会话,您可以 添加对方为好友以发送消息”
    node.js中http.respone.end方法概述
    niginx:duplicate MIME type "text/html" in nginx.conf 错误(转载)
    大三暑假实习,我们可以怎么做
    一个Java程序员的实习总结(2)
    正式工作的前奏——一个Java程序员的实习总结(1)
    【个人】当我秀智商的时候我秀什么
    基于java的设计模式入门(1)——为什么要学习设计模式
    【个人】我不愿让你一个人
  • 原文地址:https://www.cnblogs.com/ksir16/p/8041457.html
Copyright © 2011-2022 走看看