0

我有一个哈希值。这个哈希有一个字典。我需要在其中找到所有具有相同根的匹配项。例如,我有:

#<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". 如何按根获取此哈希中的所有单词?例如

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
4

3 回答 3

1

看起来我的find方法与@sawa 的方法非常相似。(我相信@sawa 是第一个教我在这种情况下使用injectwith的人&:[],所以这很合适。)

鉴于:

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')                                                                                                                                                                                                        
# => []
于 2013-07-14T10:00:10.037 回答
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. 然后,您需要扩展该哈希并将其与前缀组合。对于这部分,您可能需要参考此处的答案。

于 2013-07-14T09:10:36.040 回答
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"]
于 2013-07-14T12:00:00.630 回答