2017-07-19 3 views
0

J'essaye d'implémenter un trie dans Ruby mais je n'arrive pas à comprendre quel est le problème avec mes méthodes print + collect.ruby ​​trie mise en œuvre numéro de référence

Je viens de mettre en œuvre la même chose dans JS et fonctionne bien. Je suppose que le problème pourrait être que Ruby est passé par référence (contrairement à JS) et comment l'assignation variable fonctionne dans Ruby.

Donc, si je lance le code avec string.clone comme argument quand je l'appelle récursivement la fonction collect puis-je obtenir:

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

et si je passe string alors:

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

Toute idée comment répare ça?

le code:

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 

Répondre

1

string concat la mute de chaîne de Ruby et ne retourne pas une nouvelle chaîne. Vous pouvez vouloir le + operator à la place. Donc, changer fondamentalement les 2 lignes recueillent l'intérieur de la boucle for comme ci-dessous:

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

, vous voulez probablement soit toujours initialiser @words à vide print avant d'appeler collect, ou en faire une variable locale dans print et passe à collect.

+0

Cela fonctionne. J'ai dû faire les deux changements (nouvelle variable et en utilisant + opérateur). J'ai seulement essayé ces solutions séparément. –