You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lua递归实现Heap排列算法 存储排列结果全重复问题排查

问题根因

Lua中表(table)是引用类型,赋值、传参、存入其他表时传递的都是同一块内存的引用,不会自动复制表内容。
你的代码里整个递归流程始终在原地修改传入的同一个表a,每次满足k==1时往perm里存的都是这个a的引用,没有保存当时a的内容快照。
递归过程中你在k==1分支当场打印a时,后续的交换操作还没执行,所以调试输出能看到正确的排列;但等全部递归跑完,a经过多轮交换已经回到初始状态{1,2,3},perm里存的6个引用全部指向这同一个表,打印出来自然全是{1,2,3}。

修复方案

往perm存储排列时,先对当前的a做一次浅拷贝,把副本存入perm即可(表内元素都是数字,浅拷贝完全满足需求)。
将原来的perm[#perm + 1] = a替换为拷贝逻辑:

-- 生成当前a的副本
local temp = {}
for i = 1, #a do
  temp[i] = a[i]
end
perm[#perm + 1] = temp
修复后完整代码
function generateperm (k,a)
  if k == 1 then
    -- 存储当前排列的副本,而非原表引用
    local cur = {}
    for i = 1, #a do
      cur[i] = a[i]
    end
    perm[#perm + 1] = cur
    io.write(table.unpack(cur))
    io.write("\n")
  else
    for i=1,k do
      generateperm(k-1,a)
      if k % 2 == 0 then
        a[i],a[k] = a[k],a[i]
      else
        a[1],a[k] = a[k],a[1]
      end
    end
  end
end

perm = {}
generateperm(3,{1,2,3})

print("==== 最终存储结果 ====")
for _, p in ipairs(perm) do
  io.write(table.unpack(p))
  io.write("\n")
end

运行后最终存储的6个排列和调试输出完全一致,为1-3的全部全排列。

注:原代码最后遍历打印的循环中,内外层迭代都使用了k,v作为变量名,内层变量会覆盖外层,属于易引发bug的写法,修复版中已调整迭代变量名避免冲突。

内容的提问来源于stack exchange,提问作者hmpf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:01:15