ruby trie实现参考问题

时间:2017-07-19 10:14:31

标签: ruby algorithm data-structures tree trie

我正在尝试在Ruby中实现trie,但无法弄清楚我的print + collect方法存在什么问题。

我刚刚在JS中实现了相同的功能,正常工作。我想问题可能是Ruby通过引用传递(与JS不同)以及变量赋值如何在Ruby中工作。

因此,当我递归调用string.clone函数时,如果我以collect作为参数运行代码,那么我得到:

["peter", "peter", "petera", "pdanny", "pdjane", "pdjanck"]

如果我通过string,那么:

["peterradannyjaneck", "peterradannyjaneck", "peterradannyjaneck", "peterradannyjaneck", "peterradannyjaneck", "peterradannyjaneck"]

任何想法如何解决这个问题?

代码:

class Node
  attr_accessor :hash, :end_node, :data

  def initialize
    @hash = {}
    @end_node = false
    @data = data
  end

  def end_node?
    end_node
  end
end

class Trie
  def initialize
    @root = Node.new
    @words = []
  end

  def add(input, data, node = @root)
    if input.empty?
      node.data = data
      node.end_node = true
    elsif node.hash.keys.include?(input[0])
      add(input[1..-1], data, node.hash[input[0]])
    else
      node.hash[input[0]] = Node.new
      add(input[1..-1], data, node.hash[input[0]])
    end
  end

  def print(node = @root)
    collect(node, '')
    @words
  end

  private

  def collect(node, string)
    if node.hash.size > 0
      for letter in node.hash.keys
        string = string.concat(letter)
        collect(node.hash[letter], string.clone)
      end

      @words << string if node.end_node?
    else
      string.length > 0 ? @words << string : nil
    end 
  end
end

trie = Trie.new
trie.add('peter', date: '1988-02-26')
trie.add('petra', date: '1977-02-12')
trie.add('danny', date: '1998-04-21')
trie.add('jane', date: '1985-05-08')
trie.add('jack', date: '1994-11-04')
trie.add('pete', date: '1977-12-18')
print trie.print

1 个答案:

答案 0 :(得分:1)

Ruby的string concat改变字符串并且不返回新字符串。您可能需要+ operator。所以基本上改变了collect的for循环中的2行,如下所示:

stringn = string + letter
collect(node.hash[letter], stringn)

此外,您可能希望在调用@words之前始终将print初始化为collect,或者将其设为print中的局部变量并将其传递给{ {1}}。