找出这两个项目集的所有可能组合?Lua

我看到类似的答案在不同的编程语言中,比如Haskell和Python,但他们都使用Lua没有的内置功能,所以请不要将这个问题标记为重复。

假设我有两个表,如下所示:

table1 = {A,B,C}
table2 = {D,E,F}

我想找出匹配这两个表中项目的所有唯一方式,答案应该是(非正式表示法):

AD,BE,CF
AD,BF,CE
AE,BD,CF
AE,BF,CD
AF,BD,CE
AF,BE,CD

所以答案将存储在一个表中,表[1]将是{{A,D},{B,E},{C,F}}以此类推。

表的长度可以是任何值,但两个表的大小都将相同。

点赞
用户4070330
用户4070330

我们可以通过归纳法获取所有洗牌方式(不是最快的方法,但很容易编写/理解)

local function deepcopy(orig)
    local copy
    if type(orig) == 'table' then
        copy = {}
        for orig_key, orig_value in next, orig, nil do
            copy[deepcopy(orig_key)] = deepcopy(orig_value)
        end
        setmetatable(copy, deepcopy(getmetatable(orig)))
    else
        copy = orig
    end

    return copy
end

local function get_shuffles(N)
  if N == 1 then
    return {{1}}
  end
  local shuffles = get_shuffles(N-1)
  local result = {}
  for index = 1, #shuffles do
    local shuffle = shuffles[index]
    for position = 1, #shuffle do
      local new_shuffle = deepcopy(shuffle)
      table.insert(new_shuffle, position, N)
      table.insert(result, new_shuffle)
    end
    local new_shuffle = deepcopy(shuffle)
    table.insert(new_shuffle, N)
    table.insert(result, new_shuffle)
  end
  return result
end

table1 = {"A", "B", "C"}
table2 = {"D","E", "F"}

assert(#table1 == #table2)

local result = {}

local shuffles = get_shuffles(#table1)
for index = 1, #shuffles do
  local shuffle = shuffles[index]
  local part = {}
  for i = 1, 3 do
    table.insert(part, {})
    table.insert(part[i], table1[i])
    table.insert(part[i], table2[shuffle[i]])
  end
  table.insert(result, part)
end

for index = 1, #result do
  print(result[index][1][1], result[index][1][2], result[index][2][1], result[index][2][2], result[index][3][1], result[index][3][2])
end
2019-11-02 11:54:13
用户308010
用户308010

另一种方法是使用以下代码。这段代码是为了帮助一个游戏(Typeshift)发现所有可能的变量字母组合而编写的。我已修改它以适应你的例子。

-- 表格数组: {{1,2},{3,4},{5,6}}
-- 应该返回 {135,136,145,146,235,236,245,246}
--
-- 这使用尾递归,所以希望lua足够聪明,不会溢出堆栈
function arrayCombine(tableArray)
  -- 定义基本情况
  if (tableArray == nil) then
      return nil
  elseif (#tableArray == 0) then
      return {}
  elseif (#tableArray == 1) then
      return tableArray[1]
  elseif (#tableArray == 2) then
      return arrayCombine2(tableArray[1], tableArray[2])
    end -- if

  -- 我们有超过2个表格的输入参数。我们想要取出*最后*两个数组,合并它们,然后递归调用这个函数,
  -- 这样我们就可以逐步向前工作。
  local lastArray = table.remove(tableArray, #tableArray)
  local nextToLastArray = table.remove(tableArray, #tableArray)
  local mergedArray = arrayCombine2(nextToLastArray, lastArray)

  table.insert(tableArray, mergedArray)

  return arrayCombine(tableArray)
end -- arrayCombine

function arrayCombine2(array1, array2)
  local mergedArray = {}

  for _, elementA in ipairs(array1) do
    for _, elementB in ipairs(array2) do
      table.insert(mergedArray, elementA .. elementB)
    end -- for
  end -- for

  return mergedArray
end -- arrayCombine2

-- 你可以这样设置它:
combinedArray = {}
table.insert(combinedArray, {"A", "B", "C"})
table.insert(combinedArray, {"D", "E", "F"})

for i,v in ipairs(arrayCombine(combinedArray)) do
  print(i,v)
end

-- 或者采用这种方式,可能会更干净:
for i,v in ipairs(arrayCombine({{"A", "B", "C"}, {"D", "E", "F"}})) do
  print(i,v)
end

无论哪种方式,它都可以产生你想要的结果。

2019-11-04 15:36:16
用户1847592
用户1847592
function get_all_combinations(arr1, arr2)
   local n, e, all_comb  = #arr1, {}, {}
   for j = 1, n do
      e[j] = arr2[j]
   end
   local function generate(m)
      if m <= 1 then
         local comb = {}
         all_comb[#all_comb + 1] = comb
         for j = 1, n do
            comb[j] = arr1[j]..e[j]  -- it should be {arr1[j], e[j]} to fulfill your requirements
         end
      else
         for j = 1, m do
            generate(m - 1)
            local k = j < m and m % 2 == 1 and 1 or j
            e[k], e[m] = e[m], e[k]
         end
      end
   end
   generate(n)
   return all_comb
end

for i, v in ipairs(get_all_combinations({"A", "B", "C"}, {"D", "E", "F"})) do
  print(i, table.concat(v, ";"))
end
function get_all_combinations(arr1, arr2)
   local n, e, all_comb  = #arr1, {}, {}
   for j = 1, n do
      e[j] = arr2[j]
   end
   local function generate(m)
      if m <= 1 then
         local comb = {}
         all_comb[#all_comb + 1] = comb
         for j = 1, n do
            comb[j] = arr1[j]..e[j]  -- it should be {arr1[j], e[j]} to fulfill your requirements
         end
      else
         for j = 1, m do
            generate(m - 1)
            local k = j < m and m % 2 == 1 and 1 or j
            e[k], e[m] = e[m], e[k]
         end
      end
   end
   generate(n)
   return all_comb
end

for i, v in ipairs(get_all_combinations({"A", "B", "C"}, {"D", "E", "F"})) do
  print(i, table.concat(v, ";"))
end
2019-11-04 18:32:14