2014-12-07 84 views
0
hash = { 
    "d" => { 
    "o" => { 
     "g" => { 
     "s" => {} 
     }, 
     "l" => { 
     "l" => {} 
     }, 
     "o" => { 
     "m" => {} 
     } 
    } 
    }, 
    "b" => { 
    "o"=>{ 
     "o"=>{ 
     "m"=>{} 
     } 
    } 
    } 
} 

trie.print(hash) 

内特里类有方法称为print打印trie取钥匙:如何内哈希对象

def print(trie) 
    trie.each do |k,v| 
    @res.concat(k) 
    print(trie[k]) if trie[k].length > 0 
    unless trie[k].length > 0 
     @result << @res unless trie[k].length > 0 
     @res = "" 
     p @result 
    end 
    end 
end 

上述方法打印:

["dogs", "ll", "om", "boom"] 

但我要打印:

["dogs" , "doll", "doom" , "boom"] 

回答

0

我已将该函数更名为compose以避免与Kernel#print发生冲突。原因是我从内部调用这个函数,它应该可以调用,而不必明确地指向一个对象。您使用的方法不会“重复使用”遍历的前缀。执行此操作的最常见方法是使用递归并在参数中构建该前缀。

我有这个递归函数。递归是处理树木的常用方法。它接受一个“subtrie”和它放在下面的前缀(默认为空字符串,如果没有给出)。递归基础:如果我们得到一个空的子查询,我们返回一个构建前缀的单元素数组。更高级别将返回从给定“子路径”构建的前缀数组。

def compose(trie, prefix="") 
    trie.flat_map do |k, v| 
    new_prefix = prefix + k 
    results = compose(v, new_prefix) 
    results.empty? ? new_prefix : results 
    end 
end 

注意flat_map,否则(与map),它会输出一个深度嵌套结构数组与叶内置了前缀更换您的线索。

UPD:新版本返回空子数组的空数组。

+0

谢谢,它按照通缉的方式工作。做了小改动。 res = compose(v,前缀+ k) @ result << res除非trie [k] .length!= 0 – 2014-12-07 14:26:54

+0

@HariKrishnan不是这个函数已经用'empty?'来做这个了吗 – 2014-12-07 14:34:08

+0

不,空字符串也包含在结果。 @ D方,然后我做了这个以避免空。 – 2014-12-07 14:56:32

2

我认为我们不必传递前缀。

def compose(trie) 
    trie.flat_map do |k, v| 
    v.empty? ? k : compose(v).map{|sv| "#{k}#{sv}"} 
    end  
end 
+0

...而是将其附加到就地的结果中。很好,是的。除了不需要内部'flat_map'外,'map'就足够了。 – 2014-12-07 16:16:55

+0

谢谢,@D方。 – nickcen 2014-12-08 15:14:59

+0

谢谢,@nickcen – 2014-12-09 04:30:38