Я пытаюсь построить реализацию Trie на Java, что мне удалось сделать. Основная часть реализации выполнена, у меня есть методы, чтобы добавить слово или проверить, содержит ли слово слово в структуре, но у меня возникают проблемы при попытке напечатать дерево.
Я пытаюсь распечатать дерево в формате .dot
, чтобы иметь возможность создать файл дерева .pdf
, используя GraphViz.
В настоящее время у меня есть метод print
для класса TrieNode
, который правильно печатает все узлы в правильном формате, кроме индексов. Я не могу получить функцию, чтобы найти правильные номера индекса для соединений узла.
Вот минимальный рабочий пример:
Trie
Класс:
package trie;
import trie.*;
public class Trie {
private TrieNode root;
public Trie () {
this.root = new TrieNode();
}
public TrieNode getRoot() {
return this.root;
}
public void add(String word) {
this.getRoot().add(word);
}
public boolean contains(String word) {
int current;
int length = word.length();
TrieNode crawler = this.getRoot();
for (current = 0; current < length; current++) {
char currentChar = word.charAt(current);
if (!(crawler.getChildren().containsKey(currentChar))) {
return false;
}
crawler = crawler.getChildren().get(currentChar);
}
return (crawler.isWord());
}
public static void main(String[] args) {
Trie t = new Trie();
t.add("apples");
t.add("bananas");
System.out.println(t.getRoot().print(0, 1));
}
}
TrieNode
Класс:
package trie;
import trie.*;
import java.util.*;
public class TrieNode {
private HashMap<Character, TrieNode> children;
private String content;
private boolean isWord;
public TrieNode() {
this.children = new HashMap<Character, TrieNode>();
this.content = "";
this.isWord = false;
}
public TrieNode(String word, Character charToAdd) {
this.children = new HashMap<Character, TrieNode>();
this.content = word + String.valueOf(charToAdd);
this.isWord = true;
}
public String getContent() {
return this.content;
}
public HashMap<Character, TrieNode> getChildren() {
return this.children;
}
public boolean isWord() {
return this.isWord;
}
public void makeWord() {
this.isWord = true;
}
public void addChild(Character charToAdd) {
TrieNode child = new TrieNode(this.getContent(), charToAdd);
child.isWord = false;
this.getChildren().put(charToAdd, child);
}
public void add(String word) {
if (word.length() == 0) {
this.makeWord();
} else {
char first = word.charAt(0);
if (!(this.getChildren().containsKey(first))) {
this.addChild(first);
}
this.getChildren().get(first).add(word.substring(1));
}
}
public String print(int from, int to) {
String res = "";
if (this.getChildren().isEmpty()) {
from = 0;
to = to + 1;
return "";
} else {
for (char c : this.getChildren().keySet()) {
res += String.format("\t %d -> %d [label=\" %s\"]\n", from, to, c);
res += this.getChildren().get(c).print(to, to+1);
}
}
return res;
}
}
Результаты выполнения программы main
дают:
0 -> 1 [label=" a"]
1 -> 2 [label=" p"]
2 -> 3 [label=" p"]
3 -> 4 [label=" l"]
4 -> 5 [label=" e"]
5 -> 6 [label=" s"]
0 -> 1 [label=" b"]
1 -> 2 [label=" a"]
2 -> 3 [label=" n"]
3 -> 4 [label=" a"]
4 -> 5 [label=" n"]
5 -> 6 [label=" a"]
6 -> 7 [label=" s"]
Я пытаюсь заставить его вернуться:
0 -> 1 [label=" a"]
1 -> 2 [label=" p"]
2 -> 3 [label=" p"]
3 -> 4 [label=" l"]
4 -> 5 [label=" e"]
5 -> 6 [label=" s"]
0 -> 7 [label=" b"]
7 -> 8 [label=" a"]
8 -> 9 [label=" n"]
9 -> 10 [label=" a"]
10 -> 11 [label=" n"]
11 -> 12 [label=" a"]
12 -> 13 [label=" s"]
Индексы должны вернуться туда, где находится корневой индекс, но я не могу найти способ помешать его сбросу ...
РЕДАКТИРОВАТЬ: единственная переменная, которую я должен изменить, это переменная to
, но кажется, что она не может быть переопределена вне контекста
У вас есть идеи?