Je me suis donc construit une structure de données trie
en Java mais au lieu de tableaux contenant LinkedList
s pour les enfants de chaque noeud. Mais j'ai quelques problèmes. Le premier mot est ajouté très bien, mais sur le second mot, il compare toujours les mauvais préfixes. Par exemple, je commence par ajouter "at". Cela marche. Puis-je ajouter « Bonjour » et voici le résultat:Structure de données Trie en Java
adding 'at'
CURRENT CHAR IS: a
List is empty, can't iterate
List is empty, can't iterate
Can't find this char, adding node...
Returning child
CURRENT CHAR IS: t
List is empty, can't iterate
List is empty, can't iterate
Can't find this char, adding node...
END OF LINE; SET IT TO TRUE--------------
Returning child
adding 'Hello'
CURRENT CHAR IS: H
List is NOT empty
char H lista a?
false
List is empty, can't iterate
List is NOT empty
char H lista a?
false
List is empty, can't iterate
Can't find this char, adding node...
Returning child
CURRENT CHAR IS: e
List is NOT empty
char e lista at?
false
List is empty, can't iterate
List is NOT empty
char e lista at?
false
List is empty, can't iterate
Can't find this char, adding node...
Returning child
CURRENT CHAR IS: l
List is empty, can't iterate
List is empty, can't iterate
Can't find this char, adding node...
Returning child
CURRENT CHAR IS: l
List is empty, can't iterate
List is empty, can't iterate
Can't find this char, adding node...
Returning child
CURRENT CHAR IS: o
List is empty, can't iterate
List is empty, can't iterate
Can't find this char, adding node...
END OF LINE; SET IT TO TRUE--------------
Voici mon code (désolé pour toutes les impressions et commentaires, ont été mise au point pendant quelques heures) Trie
public class Trie {
private Node root;
private int size;
/**
* Creates the root node and sets the size to 0.
*/
public Trie() {
root = new Node();
size = 0;
}
/**
* Adds a new word to the trie.
*
* @param word
* @return
*/
//vi lägger in "Hello"
public boolean add(String word) {
System.out.println("adding " + word);
Node curr = root;
if (curr == null || word == null) {
return false;
}
int i = 0;
char[] chars = word.toCharArray();
// Loop through all letters in the word.
while (i < chars.length) {
System.out.println("lengt = " + chars.length);
LinkedList<Node> children = curr.getChildren();
// If the children nodes does not contain the letter at i.
System.out.println("BEFORE CURRENT CHAR IS: " + chars[i]);
if (!childContain(children, String.valueOf(chars[i]))) {//TODO? listan är tom.
// Insert a new node
insertNode(curr, chars[i]);
System.out.println("Can't find this word, adding...");
// if we have traversed all letters.
if (i == chars.length - 1) {
System.out.println("END OF LINE; SET IT TO TRUE--------------");
// Get the child and set word to true ie we have found it.
getChild(curr, chars[i]).setWord(true);
size++;
return true;
}
}
// get the current child.
curr = getChild(curr, chars[i]); //NOT SURE ABOUT THIS!
// If the current childs text is equal the word or not the word.
if (curr.getText().equals(word) && !curr.isWord()) {
// set the current word to true.
curr.setWord(true);
size++;
return true;
}
i++;
}
return false;
}
/**
* Returns true if the given string is found.
* TODO: FIX!
* @param str
* @return
*/
public boolean find(String str) {
System.out.println(str);
System.out.println("-----------------------------------------");
LinkedList<Node> children = root.getChildren();
Node node = null;
char[] chars = str.toCharArray();
//Loop over all letters.
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
//If child contains c.
if (childContain(children, String.valueOf(c))) {
System.out.println("DET FINNS");
//get the child and it's children.
node = getChild(root, c);
children = node.getChildren();
} else {
System.out.println("DET FINNS INGET");
return false;
}
}
return true;
}
/**
* Inserts a new Node with a char.
*
* @param node
* @param c
* @return
*/
private Node insertNode(Node node, Character c) {
if (childContain(node.getChildren(), String.valueOf(c))) {
return null;
}
Node next = new Node(node.getText() + c.toString());
node.getChildren().add(next);
return next;
}
/**
* Retrieves a given node's child with the character c
*
* @param trie
* @param c
* @return
*/
private Node getChild(Node node, Character c) {
LinkedList<Node> list = node.getChildren();
Iterator<Node> iter = list.iterator();
while (iter.hasNext()) {
Node n = iter.next();
if (n.getText().equals(String.valueOf(c)));
{
System.out.println("Returning child");
return n;
}
}
System.out.println("Returning null"); // This could never happen
return null;
}
/**
* Checks if any child contains the char c.
*
* @param list
* @param c
* @return
*/
private boolean childContain(LinkedList<Node> list, String c) {
Iterator<Node> iter = list.iterator();
while (iter.hasNext()) {
System.out.println("List is NOT empty");
Node n = iter.next();
//GÖr en substräng av den existerande noden
System.out.println("char " + (c) +" lista " + n.getText() + "?");
System.out.println(n.getText().equals(c));
if (n.getText().equals(c))
{
return true;
}
}
System.out.println("List is empty, can't iterate");
return false;
}
/**
* Returns the trie's size.
*
* @return
*/
public int getSize() {
return size;
}
}
Noeud:
public class Node {
private boolean isWord;
private String text;
private LinkedList<Node> children;
public Node() {
children = new LinkedList<Node>();
text = "";
isWord = false;
}
public Node(String text) {
this();
this.text = text;
}
public LinkedList<Node> getChildren(){
return children;
}
public boolean isWord() {
return isWord;
}
public void setWord(boolean isWord) {
this.isWord = isWord;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
@Override
public String toString(){
return text;
}
}
Quel type de Trie est-il ? avez-vous un caractère par nœud ou une chaîne? – Asoub
J'ai utilisé le débogueur. Le problème principal est que mon algrotihm pour ajouter semble aller en profondeur d'abord au lieu de créer un nouveau nœud. Je compare d'abord H avec a puis H avec t. Alors je comare e avec au. Et puis je suis à la fin de la liste. Quelque chose ne va pas lorsque je mets en place le nœud sur lequel nous sommes. Mes nœuds ont le type de données String, mais en réalité, je ne fais que stocker un seul caractère. – ioou
Vous devriez d'abord refactoriser votre code: utilisez 'char' partout, sauf pour' addWord (String s) 'bien sur. Ensuite, travaillez avec 'Node' dans votre' Trie', sans 'LinkedList'. Cela signifie que 'Node' devrait avoir la méthode' getChild() ', qui retourne null s'il n'y a pas d'enfant avec la lettre. 'insertNode()' devrait également être dans la classe 'Node'. Ainsi, le 'Trie' vérifiera seulement si un noeud a un enfant avec une lettre, sinon, l'insérera, et si c'est le caractère final, mettez-le à" vrai ". Cela devrait faciliter votre débogage. – Asoub