【问题标题】:Finding every combination of elements in a table (Lua/PseudoCode)查找表中元素的每个组合(Lua/PseudoCode)
【发布时间】:2012-10-15 02:23:32
【问题描述】:

我正在尝试使用表中元素的每一个组合来执行一个函数。 (在 Lua 中)。表格和元素可以更改,但结构将保持不变。该表的组织方式使得其中的 [1] 将是函数的第一个参数,依此类推。

如果这是我有的桌子,

Table = {
    [1] = {Player1, Player2}
    [2] = {PlayerA, PlayerB, PlayerC}
    [3] = {PlayerOne, PlayerTwo}
}

如果我手动写出来,它可能看起来像这样:(假设函数名为 Exe)。

Exe(Player1, PlayerA, PlayerOne)
Exe(Player2, PlayerA, PlayerOne)
Exe(Player3, PlayerA, PlayerOne)

Exe(Player1, PlayerB, PlayerOne)
Exe(Player2, PlayerB, PlayerOne)
Exe(Player3, PlayerB, PlayerOne)

Exe(Player1, PlayerC, PlayerOne)
Exe(Player2, PlayerC, PlayerOne)
Exe(Player3, PlayerC, PlayerOne)


Exe(Player1, PlayerA, PlayerTwo)
Exe(Player2, PlayerA, PlayerTwo)
Exe(Player3, PlayerA, PlayerTwo)

Exe(Player1, PlayerB, PlayerTwo)
Exe(Player2, PlayerB, PlayerTwo)
Exe(Player3, PlayerB, PlayerTwo)

Exe(Player1, PlayerC, PlayerTwo)
Exe(Player2, PlayerC, PlayerTwo)
Exe(Player3, PlayerC, PlayerTwo)

但是,我不想把它写出来,这违反了我的一般经验法则,即如果你在程序中复制和粘贴,那你就做错了。

因此,我想查看表格并执行每一个可能的组合。问题是表格可以(可能)在其中包含任意数量的表格,并且表格内部的表格可能具有无限数量的值。

例如,表格最终可能如下所示:

Table = {
    [1] = {Player1, Player2}
    [2] = {PlayerA}
    [3] = {PlayerOne}
}

手动执行最终会是这样:

Exe(Player1, PlayerA, PlayerOne)
Exe(Player2, PlayerA, PlayerOne)

另外,表格可能会这样结束:

Table = {
    [1] = {Player1, Player2}
    [2] = {PlayerA}
    [3] = {PlayerOne}
    [4] = {PlayerUno, PlayerDos}
    [5] = {PlayerApple, PlayerBoy, PlayerCat, PlayerDog}
}

执行最终会像..

Exe(Player1, PlayerA, PlayerOne, PlayerUno, PlayerApple)
Exe(Player2, PlayerA, PlayerOne, PlayerUno, PlayerApple)

Exe(Player1, PlayerA, PlayerOne, PlayerDos, PlayerApple)
Exe(Player2, PlayerA, PlayerOne, PlayerDos, PlayerApple)


Exe(Player1, PlayerA, PlayerOne, PlayerUno, PlayerBoy)
Exe(Player2, PlayerA, PlayerOne, PlayerUno, PlayerBoy)

Exe(Player1, PlayerA, PlayerOne, PlayerDos, PlayerBoy)
Exe(Player2, PlayerA, PlayerOne, PlayerDos, PlayerBoy)


Exe(Player1, PlayerA, PlayerOne, PlayerUno, PlayerCat)
Exe(Player2, PlayerA, PlayerOne, PlayerUno, PlayerCat)

Exe(Player1, PlayerA, PlayerOne, PlayerDos, PlayerCat)
Exe(Player2, PlayerA, PlayerOne, PlayerDos, PlayerCat)


Exe(Player1, PlayerA, PlayerOne, PlayerUno, PlayerDog)
Exe(Player2, PlayerA, PlayerOne, PlayerUno, PlayerDog)

Exe(Player1, PlayerA, PlayerOne, PlayerDos, PlayerDog)
Exe(Player2, PlayerA, PlayerOne, PlayerDos, PlayerDog)

如您所见,我找到了一种模式...我能够将上面的“执行”内容划分为段/组,例如第 1 行和第 2 行有一个变化。然后,它们被复制到第 4 行和第 5 行,但下一个变量 get 已更改。

如您所见,我无法将该模式放入代码中。我认为将需要一些函数递归,但我不知道如何将它拉下来或通过它递归。我在想我将不得不使用带有 ... 作为参数的函数和 unpack 函数,但我不确定这将如何工作。

另外,这是必需的,而不仅仅是手动复制和粘贴它(实际上更容易),是因为将生成表格的内容。

你们能帮帮我吗?

【问题讨论】:

    标签: function data-structures recursion matrix lua


    【解决方案1】:

    使用递归。

    想象一个函数map_all (fcn, tab, idx, ...) 将fcn 映射到tab[1] 到tab[idx] 前面的所有表元素的乘积...

    基本情况是idx 小于 1。在这种情况下,只需应用 fcn(...)

    否则,map_all(fcn, tab, idx-1, <el>, ...) 用于 tab[idx] 中的所有 <el>

    function map_all (fcn, tab, idx, ...)
        if idx < 1 then
            fcn(...)
        else
            local t = tab[idx]
            for i = 1, #t do map_all(fcn, tab, idx-1, t[i], ...) end
        end
    end
    

    所以,

    > Table = {
    >>     [1] = {'Player1', 'Player2'},
    >>     [2] = {'PlayerA', 'PlayerB', 'PlayerC'},
    >>     [3] = {'PlayerOne', 'PlayerTwo'}
    >> }
    > map_all(print, Table, #Table)
    Player1 PlayerA PlayerOne
    Player2 PlayerA PlayerOne
    Player1 PlayerB PlayerOne
    Player2 PlayerB PlayerOne
    Player1 PlayerC PlayerOne
    Player2 PlayerC PlayerOne
    Player1 PlayerA PlayerTwo
    Player2 PlayerA PlayerTwo
    Player1 PlayerB PlayerTwo
    Player2 PlayerB PlayerTwo
    Player1 PlayerC PlayerTwo
    Player2 PlayerC PlayerTwo
    

    和

    > Table = {
    >>     [1] = {'Player1', 'Player2'},
    >>     [2] = {'PlayerA'},
    >>     [3] = {'PlayerOne'}
    >> }
    > map_all(print, Table, #Table)
    Player1 PlayerA PlayerOne
    Player2 PlayerA PlayerOne
    

    和

    > Table = {
    >>     [1] = {'Player1', 'Player2'},
    >>     [2] = {'PlayerA'},
    >>     [3] = {'PlayerOne'},
    >>     [4] = {'PlayerUno', 'PlayerDos'},
    >>     [5] = {'PlayerApple', 'PlayerBoy', 'PlayerCat', 'PlayerDog'},
    >> }
    > map_all(print, Table, #Table)
    Player1 PlayerA PlayerOne   PlayerUno   PlayerApple
    Player2 PlayerA PlayerOne   PlayerUno   PlayerApple
    Player1 PlayerA PlayerOne   PlayerDos   PlayerApple
    Player2 PlayerA PlayerOne   PlayerDos   PlayerApple
    Player1 PlayerA PlayerOne   PlayerUno   PlayerBoy
    Player2 PlayerA PlayerOne   PlayerUno   PlayerBoy
    Player1 PlayerA PlayerOne   PlayerDos   PlayerBoy
    Player2 PlayerA PlayerOne   PlayerDos   PlayerBoy
    Player1 PlayerA PlayerOne   PlayerUno   PlayerCat
    Player2 PlayerA PlayerOne   PlayerUno   PlayerCat
    Player1 PlayerA PlayerOne   PlayerDos   PlayerCat
    Player2 PlayerA PlayerOne   PlayerDos   PlayerCat
    Player1 PlayerA PlayerOne   PlayerUno   PlayerDog
    Player2 PlayerA PlayerOne   PlayerUno   PlayerDog
    Player1 PlayerA PlayerOne   PlayerDos   PlayerDog
    Player2 PlayerA PlayerOne   PlayerDos   PlayerDog
    > 
    

    【讨论】:

    • 所以,作为一个遍历,这个函数会取出主表中的顶部值,所以在这种情况下: > Table = { >> [1] = {'Player1', 'Player2 '}, >> [2] = {'PlayerA'}, >> [3] = {'PlayerOne'} >> } 它会拉出[3],然后拉出[2],然后会拉出[1]。所以 ... 部分会慢慢转移以适应这些,直到所有论点都存在?此外,它会在没有任何东西可以拉出时执行,对吧?只是想弄清楚它是如何工作的......
    • 是的,它从最后一个子表开始遍历主表,将值推送到...的前面,并在最终用完子表时调用该函数。当函数返回时,它会返回上一级到下一次迭代;当迭代完成时,它也会返回到下一个迭代。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    相关资源
    最近更新 更多