Что вы реализовали is called"trie". Вы можете посмотреть на существующие реализации.
То, что вы использовали для хранения дочерних узлов, называется хеш-таблицей, и вы можете использовать стандартные реализации и не выполнять его самостоятельно, если у вас нет очень-очень конкретных причин для этого. У вашей реализации есть некоторые ограничения (диапазон символов, например).
Я думаю, ваш код содержит ошибку в методе has
:
...
else if (letter[val].flag==true || word.length()==1) {
return true;
}
Если этот метод предназначен для возврата верно, если есть строки, начинающиеся с word
, то он не должен проверить flag
. Если он должен возвращать true, если есть только точное совпадение, он не должен проверять word.length()
.
И, наконец, решение вашего вопроса: не оптимальное, но самым простым решением было бы сделать метод, который берет строку и возвращает узел, соответствующий этой строке, и метод, который составляет все слова из узла. Что-то вроде этого (не проверено):
class Tree {
...
public List<String> matches(CharSequence prefix) {
List<String> result = new ArrayList<>();
if(r != null) {
Node n = r._match(prefix, 0);
if(n != null) {
StringBuilder p = new StringBuilder();
p.append(prefix);
n._addWords(p, result);
}
}
return result;
}
}
class Node {
...
protected Node _match(CharSequence prefix, int index) {
assert index <= prefix.length();
if(index == prefix.length()) {
return this;
}
int val = prefix.charAt(index) - 'a';
assert val >= 0 && val < letter.length;
if (letter[val] != null) {
return letter[val].match(prefix, index+1);
}
return null;
}
protected void _addWords(StringBuilder prefix, List<String> result) {
if(this.flag) {
result.add(prefix.toString());
}
for(int i = 0; i<letter.length; i++) {
if(letter[i] != null) {
prefix.append((char)(i + 'a'));
letter[i]._addWords(prefix, result);
prefix.delete(prefix.length() - 1, prefix.length());
}
}
}
}
Спасибо за ответ! Я отдам его. Что касается ошибки в моем методе, почему он должен возвращать true для точных совпадений? Должен ли он также не возвращаться, если вводится «tes»? Да, это не точное слово, но когда пользователь вводит «tes», он должен отображать все, что начинается с этого слова – Teddy13
@ Teddy13, я не знаю, что именно должен делать этот метод, но если он должен вернуть true для ' tes', тогда он не должен проверять истинность 'flag' как истинного (поскольку для' tes' нет экземпляра 'Node' с' flag = true'. Посмотрите на мой impl 'Node._match', он делает то, что вы хотите (просто возвращает узел вместо boolean, для дальнейшего использования). – khachik