【问题标题】:Explanation of Ruby code for building Trie data structures用于构建 Trie 数据结构的 Ruby 代码说明
【发布时间】:2012-01-28 02:22:55
【问题描述】:

所以我有这个从 wikipedia 抓取的 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 上运行它,每次输出 node,它每次都给我一个空哈希 {},但是当我实际使用参数 'dogs' 字符串调用该函数构建时,它实际上确实有效,并输出{"d"=>{"o"=>{"g"=>{"s"=>{}}}}},这是完全正确的。

这可能更像是一个 Ruby 问题,而不是关于算法如何工作的实际问题。我猜我并没有足够的 Ruby 知识来破译那里发生的事情。

【问题讨论】:

  • “每次我输出节点”是什么意思?不确定您在寻找什么样的答案——您是否在纸上追踪了一个小字符串的算法?很短。
  • 我在输入 node = prev_node['a'] 后在控制台上输入了 'node',然后它返回类似 => {} 的东西,这意味着哈希到空对象,然后我输入 node = node['b'],尝试通过传入不同的字符作为键来模拟 for 循环。当我在那之后再次输入'node'时,它当然返回nil。我只是想知道当我每次跟踪它时它如何产生 {"d"=>{"o"=>{"g"=>{"s"=>{}}}}} 时,它看起来总是空的
  • 我仍然建议用一张纸来跟踪算法,跟踪每一步并写下所有变量的值。特别注意prev_node[cur] = Hash.new,并考虑prev_node[cur] 是什么——但请记住prev_node 本身是一个带有字符键的散列,它恰好指向一个空散列(对于一次迭代)。
  • 我不明白你的问题是什么。

标签: ruby irb


【解决方案1】:

您可能会迷失在一堆乱七八糟的代码中,它采用了一种似乎更适合 C++ 而不是 Ruby 的方法。下面是同样的东西,格式更简洁,使用特殊情况的 Hash 进行存储:

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

它的工作原理完全相同,但指针等方面几乎没有相同的混乱:

trie = Trie.new
trie.build('dogs')
puts trie.inspect

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

【讨论】:

  • 如何在 Trie 中添加另一个单词?
  • @EricDuminil 你可以用不同的词多次调用build
  • 谢谢,我没注意到build 是一个实例方法。不过,add 可能更合适。根据数据,添加一些关于最终节点的信息可能会很有趣:在foobar 之后添加foo 不会改变当前结构的任何内容。
  • @EricDuminil 这只是更强大版本的基础,所以如果您需要这种东西,请务必扩展! build 是原问题中给出的方法,所以我只是使用它。
  • 谢谢。这个问题在“ruby trie”查询中相当高,这就是我冒昧评论它的原因。不错的方法,顺便说一句!
【解决方案2】:

我认为您只是错误地使用了 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 2016-02-19
    • 2020-03-09
    • 1970-01-01
    相关资源
    最近更新 更多