У меня есть дерево префиксов для хранения огромной коллекции слов. Прямо сейчас, если я хочу найти все слова с общим префиксом, скажем, «а», я сначала извлекаю первый узел, содержащий а, а затем исчерпывающе ищу в глубине в дочерних узлах первого узла. Хотя эта идея выглядит наивной и простой, на самом деле она жалко медленная, если возможное количество слов с общим префиксом ОЧЕНЬ ВЫСОКОЕ (> 20K). Есть ли другой способ эффективно получить все слова, начинающиеся с общего префикса? Или я должен принять какую-то другую структуру данных? Заранее благодарю вас.
EDIT1 В основном я создаю полное слово, посещая каждый узел и постепенно добавляя символы. Все слова впоследствии сохраняются в векторном контейнере. И да, у меня рекурсивная реализация.
ИЗМЕНИТЬ2
vector<int> getNonEmptyEdgeIndices(Node* parent) {
vector<int> indices;
for(int i=0; i<EDGE; i++) {
if (parent->edges[i] != NULL) {
indices.push_back(i);
}
}
return indices;
}
vector<string> getSubsequentStrings(vector<string> wordsStartingWith, Node* node, string prefix) {
vector<int> indices = getNonEmptyEdgeIndices(node);
// push the word to the container if node is a leaf
if (indices.empty()) {
wordsStartingWith.push_back(prefix);
return wordsStartingWith;
}
// if frequency is set in node, push the word but still continue recursion
if (node->frequency != 0) {
wordsStartingWith.push_back(prefix);
}
// look all the children of the node
for(unsigned int i=0; i<indices.size(); i++) {
string newPrefix = prefix + getNodeChar(indices[i]);
Node* child = node->edges[indices[i]];
// recursively get the prefix for all children
wordsStartingWith = getSubsequentStrings(wordsStartingWith, child, newPrefix);
}
return wordsStartingWith;
}
vector<string> Trie::getWordsStartingWith(string prefix) {
vector<string> wordsStartingWith;
Node* lastNode = getLastNode(prefix);
if (lastNode != NULL) {
wordsStartingWith = getSubsequentStrings(wordsStartingWith, lastNode, prefix);
}
return wordsStartingWith;
}
РЕДАКТИРОВАНИЕ 3 РЕШЕНО!!! На самом деле была проблема с моей реализацией. Я передавал этот огромный контейнер векторных строк в рекурсивных вызовах, что на самом деле было проблемой. Спасибо всем за ваши добрые советы.