在Ruby中构建独特树的最快/最短路径?

时间:2009-10-19 21:52:53

标签: ruby tree query-optimization

什么是最快/最短/单线程(不可能:p)方式从树中构建唯一的元素树,其中许多元素在某些节点中重复/缺失,因为树具有已定义的集合节点(我们使用这个算法来弄清楚,所以我们不必手动完成)。

它可能是XML / JSON(哈希),或者其他什么。所以像这样:


root {
    nodes {
        nodeA {}
        nodeB {
            subNodeA {}
        }
    }
    nodes {
        nodeA {
            subNodeA {}
        }
        nodeB {
            subNodeX {}
        }
    }
}

...转换为:


root {
    nodes {
        nodeA {
            subNodeA {}
        }
        nodeB {
            subNodeA {}
            subNodeX {}
        }
    }
}

与xml相同:  

root {
    nodes {
        nodeA {
            subNodeA {}
        }
        nodeB {
            subNodeA {}
            subNodeX {}
        }
    }
}


<root>
    <nodes>
        <nodeA/>
        <nodeB>
            <subNodeA/>
        </nodeB>
    </nodes>
    <nodes>
        <nodeA>
            <subNodeA/>
        </nodeA>
        <nodeB>
            <subNodeX/>
        </nodeB>
    </nodes>
</root>

xml / json文件可能相当大(1MB +),因此不得不迭代每个元素深度优先或看起来需要一段时间。它也可以和上面的例子一样小。

1 个答案:

答案 0 :(得分:3)

这将为您提供一系列独特的路径:

require 'nokogiri'
require 'set'

xml = Nokogirl::XML.parse(your_data)
paths = Set.new
xml.traverse {|node| next if node.text?; paths << node.path.gsub(/\[\d+\]/,"").sub(/\/$/,"")}

这会让你开始吗?

[回应评论中的问题]

添加attibute-paths也很容易,但让我们至少有一点点多行:

xml.traverse do |node|
  next if node.text?
  paths << (npath = node.path.gsub(/\[\d+\]/,"").sub(/\/$/,""))
  paths += node.attributes.map {|k,v| "#{npath}@#{k}"}
end