// Returns if the word is in the trie.
 bool search(string key) {
     TrieNode *cur = root;
     for(auto ch : key) {
         cur = cur->get_child(ch);
         if (cur == nullptr)
             return false;
     }
     return cur->is_end;
 }
 // Returns if there is any word in the trie
 // that starts with the given prefix.
 bool startsWith(string prefix) {
     TrieNode *cur = root;
     for (auto ch : prefix) {
         cur = cur->get_child(ch);
         if (cur == nullptr)
             return false;
     }
     return true;
 }
 // Inserts a word into the trie.
 void insert(string s) {
     if (search(s))  return;
     
     TrieNode* cur = root;
     for (auto ch : s) {
         TrieNode *child = cur->get_child(ch);
         if (child)
             cur = child;
         else {
             TrieNode *newNode = new TrieNode(ch);
             cur->children.push_back(newNode);
             cur = newNode;
         }
         ++cur->num_of_shared_node; // parent node is shared
     }
     cur->is_end = true;
 }