我有哈希哈希。这个哈希有一个字典。我需要在其中找到具有相同根的所有匹配项。例如,我有:
#<Trie:0x00000001bf9a40 @root={
"m"=>{"a"=>{"x"=>{
:end=>true,
"i"=>{"m"=>{
:end=>true,
"i"=>{"m"=>{"l"=>{"i"=>{"a"=>{"n"=>{:end=>true}}}}}}
}},
"w"=>{"e"=>{"l"=>{"l"=>{:end=>true}}}}
}}}
}>
和字"max"
,"maxim"
,"maximilian"
,"maxwell"
。如何通过root获取此哈希中的所有单词?例如
t = Trie.new
t.add( .....# now we added words
t.find('max')
#result all words which begins from 'max'
t.find('maxim')
#result all words which begins from 'maxim' => maxim, maximilian
答案 0 :(得分:1)
看起来我的find
方法与@ sawa非常相似。 (我相信@sawa是第一次教我使用inject
和&:[]
这样的情况的人,所以这很合适。)
假设:
class Trie
def initialize(root)
@root = root # Just a shortcut to use your data and focus on your question
end
# Recurses through Hash `h` to find all words starting with `s`
def words(h, s, a=[])
h.each do |k, v|
if k == :end
a << s
else
words(v, s+k, a)
end
end
a
end
private :words
def find(start)
words(start.chars.inject(@root, &:[]), start) rescue []
end
end
t = Trie.new({"m"=>{"a"=>{"x"=>{:end=>true,
"i"=>{"m"=>{:end=>true,
"i"=>{"m"=>{"l"=>{"i"=>{"a"=>{"n"=>{:end=>true}}}}}}}},
"w"=>{"e"=>{"l"=>{"l"=>{:end=>true}}}}}}}})
你可以这样做:
t.find('max')
# => ["max", "maxim", "maximimlian", "maxwell"]
t.find('maxi')
# => ["maxim", "maximimlian"]
t.find('maximi')
# => ["maximimlian"]
t.find('maxw')
# => ["maxwell"]
t.find('x')
# => []
答案 1 :(得分:0)
这不是一个完整的答案。它只是处理前缀。
class Trie
def find prefix
expand(prefix, prefix.each_char.inject(@root, &:[])) rescue []
end
def expand prefix, affix
#TODO
end
end
鉴于t.find("maxi")
,已实施的部分prefix.each_char.inject(@root, &:[])
将返回:
{"m" => {
:end => true,
"i" => {"m" => {"l" => {"i" => {"a" => {"n" => {:end => true}}}}}}
}}
并将前缀"maxi"
传递给Trie#expand
。然后,您需要扩展该哈希并将其与前缀组合。对于该部分,您可能需要参考答案here。
答案 2 :(得分:0)
这是我的尝试
# Returns all the possible matching suffixes for the `given` string.
# trie is a map of map of .. strings delimitted by :end
# cur_word is a scratch pad for storing characters from prev level.
# Pass empty string for cur_word or create a wrapper around this function.
def all_suffix(trie, given, cur_word)
#Suffixes found in the current iteration
suffixes = []
#The current node (character at which we want the Hash)
at = given[0]
cur_word << (at || '')
cur_trie = trie[at] || trie[cur_word[-1]] || {}
#When we are at the end of the string, given.length <= 1 and we must print out all suffixes
cur_trie.each do |next_str, next_trie|
if next_str == :end
#Only if we reached the end of the `given` string
suffixes << cur_word if given.length <= 1
else
#Delete the first character and continue iteration
other_suffixes = all_suffix({ next_str => next_trie },
given[1..-1] || '',
cur_word + (given.length > 1 ? '' : next_str))
suffixes << other_suffixes.flatten if other_suffixes.size > 0
end
end
suffixes.flatten
end
trie = {
"m"=>{"a"=>{"x"=>{
:end=>true,
"i"=>{"m"=>{
:end=>true,
"i"=>{"m"=>{"l"=>{"i"=>{"a"=>{"n"=>{:end=>true}}}}}}
}},
"w"=>{"e"=>{"l"=>{"l"=>{:end=>true}}}}
}}}
}
p all_suffix(trie,“max”,“”)
["max", "maxim", "maximimlian", "maxwell"]
p all_suffix(trie,“maxi”,“”)
["maxim", "maximimlian"]