TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
trie_modern.cpp
Go to the documentation of this file.
1
7#include <iostream> // for io operations
8#include <memory> // for std::shared_ptr<>
9#include <string> // for std::string class
10
16class Trie {
17 private:
18 static constexpr size_t ALPHABETS = 26;
19
26 struct TrieNode {
27 // An array of pointers of size 26 which tells if a character of word is
28 // present or not.
29 std::shared_ptr<TrieNode> character[ALPHABETS]{nullptr};
30
31 bool isEndOfWord{false};
32 };
33
41 inline static bool hasChildren(std::shared_ptr<TrieNode> node) {
42 for (size_t i = 0; i < ALPHABETS; i++) {
43 if (node->character[i]) {
44 return true;
45 }
46 }
47 return false;
48 }
49
64 std::shared_ptr<TrieNode> removeWordHelper(const std::string& word,
65 std::shared_ptr<TrieNode> curr,
66 size_t index) {
67 if (word.size() == index) {
68 if (curr->isEndOfWord) {
69 curr->isEndOfWord = false;
70 }
71 if (hasChildren(curr)) {
72 return curr;
73 }
74 return nullptr;
75 }
76
77 size_t idx = word[index] - 'a';
78
79 // Throw a runtime error in case the user enters a word which is not
80 // present in the trie.
81 if (!curr->character[idx]) {
82 throw std::runtime_error(std::move(std::string("Word not found.")));
83 }
84
85 curr->character[idx] =
86 removeWordHelper(word, curr->character[idx], index + 1);
87
88 // This if condition checks if the node has some childern.
89 // The 1st if check, i.e. (curr->character[idx]) is checked specifically
90 // because if the older string is a prefix of some other string, then,
91 // there would be no need to check all 26 characters. Example- str1 =
92 // abbey, str2 = abbex and we want to delete string "abbey", then in
93 // this case, there would be no need to check all characters for the
94 // chars a,b,b.
95 if (curr->character[idx] || hasChildren(curr)) {
96 return curr;
97 }
98 return nullptr;
99 }
100
101 public:
103 Trie() : m_root(std::make_shared<TrieNode>()) {}
104
109 void insert(const std::string& word) {
110 auto curr = m_root;
111 for (char ch : word) {
112 size_t index = ch - 'a';
113
114 // if a node for current word is not already present in trie, create
115 // a new node for it.
116 if (!curr->character[index]) {
117 curr->character[index] = std::make_shared<TrieNode>();
118 }
119
120 curr = curr->character[index];
121 }
122 curr->isEndOfWord = true;
123 }
124
132 bool search(const std::string& word) {
133 auto curr = m_root;
134 for (char ch : word) {
135 size_t index = ch - 'a';
136
137 // if any node for a character is not found, then return that the
138 // word cannot be formed.
139 if (!curr->character[index]) {
140 return false;
141 }
142 curr = curr->character[index];
143 }
144 return curr->isEndOfWord;
145 }
146
147 // Function to remove the word which calls the helper function.
148 void removeWord(const std::string& word) {
149 m_root = removeWordHelper(word, m_root, 0);
150 }
151
152 private:
153 // data member to store the root of the trie.
154 std::shared_ptr<TrieNode> m_root;
155};
156
160int main() {
161 Trie trie;
162 trie.insert("hel");
163 trie.insert("hello");
164 trie.removeWord("hel");
165 std::cout << trie.search("hello") << '\n';
166
167 return 0;
168}
std::shared_ptr< TrieNode > removeWordHelper(const std::string &word, std::shared_ptr< TrieNode > curr, size_t index)
bool search(const std::string &word)
Trie()
constructor to initialise the root of the trie.
static bool hasChildren(std::shared_ptr< TrieNode > node)
void insert(const std::string &word)
int main()