解释用于构建Trie数据结构的Ruby代码

解释用于构建Trie数据结构的Ruby代码,ruby,irb,Ruby,Irb,我从维基百科上获取了这个ruby代码,并对其进行了一些修改: @trie = Hash.new() def build(str) node = @trie str.each_char { |ch| cur = ch prev_node = node node = node[cur] if node == nil prev_node[cur] = Hash.new() node = prev_node[

我从维基百科上获取了这个ruby代码,并对其进行了一些修改:

@trie = Hash.new()
def build(str)
    node = @trie
    str.each_char { |ch|
      cur = ch
      prev_node = node
      node = node[cur]
      if node == nil
        prev_node[cur] = Hash.new()
        node = prev_node[cur]
      end
    }
  end

build('dogs')

puts @trie.inspect
我第一次在控制台irb上运行它,每次我输出
节点
,每次
{}
它都会给我一个空哈希,但是当我实际使用参数
'dogs'
字符串调用该函数build时,它确实工作了,并输出
{“d”=>{“o”=>{“g”=>{“s”=>{}}}
,这是完全正确的


这可能更像是一个Ruby问题,而不是关于算法如何工作的实际问题。我想我没有足够的Ruby知识来解释那里发生了什么。

我认为你只是错误地使用了irb。您应该输入整个函数,然后运行它,看看是否得到正确的结果。如果它不起作用,那么你把你的整个IRB会话发布在这里怎么样

下面是您的代码的简化版本:

def build(str)
  node = @trie
  str.each_char do |ch|
    node = (node[ch] ||= {})
  end
  # not sure what the return value should be
end

<>你可能在代码混乱中迷路了,这是一种看起来比C++更适合C++的方法。以下是使用特殊大小写哈希存储的更简洁格式中的相同内容:

class Trie < Hash
  def initialize
    # Ensure that this is not a special Hash by disallowing
    # initialization options.
    super
  end

  def build(string)
    string.chars.inject(self) do |h, char|
      h[char] ||= { }
    end
  end
end

Ruby的
Enumerable
模块充满了非常有用的方法,比如
inject
,这正是您在这种情况下想要的方法。

您所说的“每次输出节点”是什么意思?不知道你在寻找什么样的答案——你有没有在纸上找到一个小字符串的算法?它很短。我在控制台上键入node=prev_node['a']之后键入'node',然后它返回类似=>{}的东西,这意味着散列到空对象,然后键入node=node['b'],试图通过传递不同的字符作为键来模拟for循环。当我在那之后再次输入'node'时,它当然返回nil。我只是想知道它怎么能产生{“d”=>{“o”=>{“g”=>{“s”=>{}}}}当我每次跟踪它时,它看起来总是空的。我仍然建议用一张纸跟踪算法,遵循每一步并写下所有变量的值。具体看<代码> PrimeNoo[Cur]=hash。新< <代码>,并考虑<代码> PrimeNoo[CUR] 是什么-但请记住,<代码> PrimeNo结本身是一个带有字符键的散列,恰好指向一个空散列(一次迭代)。。我不明白你的问题是什么。你如何在Trie中添加另一个单词?@EricDuminil你可以用不同的单词调用
build
。谢谢,我没有注意到
build
是一个实例方法<代码>添加可能更合适。根据数据的不同,添加一些关于最终节点的信息可能会很有趣:在
foobar
之后添加
foo
不会改变当前结构的任何内容。@EricDuminil它只是一个更健壮版本的基础,所以如果您需要这类内容,请务必扩展
build
是原始问题中给出的方法,所以我只是使用了它。谢谢。这个问题在“ruby trie”查询中非常重要,这就是为什么我冒昧地对此发表评论的原因。好方法,顺便说一句!
trie = Trie.new
trie.build('dogs')
puts trie.inspect