Если вы действительно хотите использовать три, тогда addToTrie()
будет действительно O (k) , где k - длина добавляемого вами слова. constructTrie()
будет принимать O (Nk) , где N - количество слов, если вы просто наберете addToTrie()
для каждого слова. Однако вам не нужно вызывать функцию addToTrie()
для каждого слова. Как только вы закончите добавлять слово, просто сбросьте указатель trie на корень trie, затем переместите указатель, когда вы перемещаетесь по текущему слову, добавляя символы по мере продвижения. Псевдокод:
trieNode *curr = trieRoot;
for each character c in document
if it's a word terminator (space etc)
add a character at curr signaling the end of the current word ('\0' maybe);
curr = trieRoot;
else if character is not a separator
add character c at curr->next->character[c];
curr = curr->next;
Это даст вам O (C) время выполнения для построения дерева, где C - количество символов в вашем документе.
Теперь возникает вопрос: зачем вам вообще нужен три? Очевидно, вы нашли способ определить, когда слово закончилось, так почему вы должны добавить свои слова в три? Это излишне. Единственная необходимая структура данных - это несколько переменных: одна для отслеживания текущего символа, одна для отслеживания предыдущего символа и одна для подсчета слов. Это легко сделать в O (C) следующим образом:
char prev = '\0';
char curr;
int count = 0;
for each character curr
if curr is a word separator and prev isn't
++count;
prev = curr;
Я думаю, что нет смысла использовать три для этой проблемы, это только усложняет вещи. Я думаю, что если бы они захотели проверить ваши знания о попытках, они бы создали проблему, в которой трив имел больше смысла.
Даже если они дали вам функцию getNextWord()
(вы ДОЛЖНЫ ее использовать? Потому что вы можете добиться большего успеха без нее), я предполагаю, что она возвращает "\ 0" или что-то еще, когда слов больше нет? Так почему вы не можете просто вызвать его, пока он не вернет "\ 0", и не посчитать такие слова? В любом случае, здесь три не имеет смысла.