解释用于构建Trie数据结构的Ruby代码
我从维基百科上获取了这个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[
@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