由于您在解析后没有显示数据的格式,因此我会猜测:)以下是我将如何将分析的数据存储在ruby对象中(为了清晰起见,使用新样式的散列键语法):
[ {yes: 2, no: 3},
{yes: 4},
{yes: 4},
{yes: -1} ]
然后,树遍历可以递归地完成。只要你的数组长度不是几千个元素,这将工作得很好。
def tree(object_number, list)
if object_number == list.size
[[object_number]]
else
list[object_number-1].values.map { |obj_num|
tree(obj_num,list)
}.inject{|a,b| a+b}.map{|l| [object_number] + l}
end
end
现在你调用该函数:
tree(1,data)
=> [[1, 2, 4], [1, 3, 4]]
data = [ {yes: 2, no: 3}, {yes: 4, no:5}, {yes:5, no:4}, {yes:5}, {yes: -1} ]
tree(1,data)
=> [[1, 2, 4, 5], [1, 2, 5], [1, 3, 5], [1, 3, 4, 5]]
它是如何工作的:建立这个名单的最简单方法是倒退,因为我们只知道路径的数目,一旦我们得到到所有这些的结尾。所以这段代码一直沿着引用到最后,当它到达最后一个对象时,它将它作为一个单元素的二维数组返回。
tree(5,list)
=> [[5]]
在递归的每一层,它需要它的结果是递归调用(返回一个列表的列表),并预置它自己的对象编号每个内部列表。所以,以下备份树:
tree(4,list) # prepends 4 to tree(5)
=> [[4,5]]
tree(3,list) # prepends 3 to tree(4) and tree(5)
=> [[3,4,5],[3,5]]
tree(2,list) # prepends 2 to tree(4) and tree(5)
=> [[2,4,5],[2,5]]
tree(1,list) # prepends 1 to tree(2) and tree(3)
=> [[1, 2, 4, 5], [1, 2, 5], [1, 3, 5], [1, 3, 4, 5]]
如果名单可能足够长,溢出的筹码,它总是能够做到这一点没有递归。递归只是这个特定问题的最简单的方法。