如何编写一个返回嵌套表中的键列表的函数?

时间:2010-02-22 18:45:53

标签: algorithm functional-programming recursion lua

我有一个分层嵌套的关联数组。它看起来像这样:

A = { 
    B = { 
        C = {}, 
        D = {}, 
    }, 
    E = { 
        F = { 
            G = {} 
        } 
    }, 
    H = {} 
}

我想编写一个返回每个键的“祖先”的函数。

所以:

f("A") = {"A"} 
f("B") = {"B","A"} 
f("C") = {"C","B","A"} 
f("G") = {"G","F","E","A"} 
f("fake") = {} 

我已经解决了我需要使用递归,但是我在编写函数时遇到了困难。有人可以给我一些关于如何编写这样一个函数的指示吗?

(请不要转介我http://xkcd.com/138/!)

4 个答案:

答案 0 :(得分:6)

只需应用递归depth-first search即可找到您的特定元素并返回路径。

构造元素X的路径的递归步骤。

  • 如果当前元素为X:返回{X}
  • 如果当前元素不是X

    1. 检查所有子节点。
    2. 获取返回有效路径的子节点并向其添加当前元素。
    3. 如果没有有效的子节点,请返回nil

答案 1 :(得分:2)

A = {
    B = {
        C = {},
        D = {},
    },
    E = {
        F = {
            G = {}
        }
    },
    H = {}
}

function f(root, find)
    -- iterate over all child values
    for k, v in pairs(root) do
        if k == find then
            -- found the match
            return({find})
        else
            -- no match, search the children
            tmp = f(root[k], find)
            if tmp ~= nil then
                table.insert(tmp, 1, k)
                return tmp
            end
        end
    end
end

print(table.concat(f(A, "G"), " "))

由于您无法检索最高阶表的名称(在本例中为A),您可能需要将此表嵌套到另一个表中,如下例所示:

r = {A = {
    B = {
        C = {},
        D = {},
    },
    E = {
        F = {
            G = {}
        }
    },
    H = {}
}
}

在这种情况下,你需要调用f(r,“G”),原因。

答案 2 :(得分:1)

如果层次结构中存在循环,则需要跟踪已访问的子表。 请参阅globals code中的Lua live demo

答案 3 :(得分:0)

这是我提出的使用Dario建议的解决方案:

function checkTable(t, key)
    if t[key] then
        return {key}
    else
        for k, subtable in pairs(t) do
            local children = checkTable(subtable,key)
            if #children ~= 0 then
                table.insert(children,1,k)
                return children
            end
        end
        return {}
    end
end