• 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

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

  • 相关阅读:
    SpringMvc 框架
    面试:你最大的长处和弱点分别是什么?这些长处和弱点对你在企业的业绩会有什么样的影响?
    线程、并发、并行、进程是什么,以及如何开启新的线程?
    面向对象三大特性
    一台客户端有三百个客户与三百个客户端有三百个客户对服务器施压,有什么区别?
    JavaScript 引擎
    Spring Data JPA简介 Spring Data JPA特点
    redo log 有什么作用?
    Spring的简介和优点?
    学习笔记——享元模式Flyweight
  • 原文地址:https://www.cnblogs.com/ksir16/p/8041457.html
Copyright © 2020-2023  润新知