class Trie {
public:
struct Node
{
vector<shared_ptr<Node>> nodes(26, nullptr);
char letter = '-';
string str{};
};
Trie() {}
void insert(string word) {
int firstLetterInt = word[0] - 'a';
if (!root.nodes[firstLetterInt])
{
root.nodes[firstLetterInt] = make_shared<Node>();
}
insert(word, 0, root.nodes[firstLetterInt]);
}
// Assumes curNode is not nullptr.
void insert(string word, int idx, shared_ptr<Node> curNode)
{
if (curNode->letter == '-')
{
curNode->letter = word[idx];
}
if (word.size()-1 == idx)
{
curNode->str = word;
}
else
{
int nextLetterInt = word[idx+1] - 'a';
if (!curNode->nodes.contains(nextLetterInt))
{
curNode->nodes[nextLetterInt] = make_shared<Node>();
}
insert(word, idx+1, curNode->nodes[nextLetterInt]);
}
}
bool search(string word) {
int firstLetterInt = word[0] - 'a';
if(root.nodes.contains(firstLetterInt))
{
return search(word, 0, root.nodes[firstLetterInt]);
}
return false;
}
bool search(string word, int idx, shared_ptr<Node> curNode)
{
if( (idx == word.size()-1) && (curNode->str == word) )
{
return true;
}
else
{
int nextLetterInt = word[idx+1] - 'a';
if(curNode->nodes.contains(nextLetterInt))
{
return search(word, idx+1, curNode->nodes[nextLetterInt]);
}
}
return false;
}
bool startsWith(string prefix) {
int firstLetterInt = prefix[0] - 'a';
if(root.nodes.contains(firstLetterInt))
{
return startsWith(prefix, 0, root.nodes[firstLetterInt]);
}
return false;
}
bool startsWith(string word, int idx, shared_ptr<Node> curNode)
{
if( idx == (word.size()-1))
{
return true;
}
else
{
int nextLetterInt = word[idx+1] - 'a';
if(curNode->nodes.contains(nextLetterInt))
{
return startsWith(word, idx+1, curNode->nodes[nextLetterInt]);
}
}
return false;
}
Node root{};
};