Stream of Characters in C++

Suppose we want to implement the StreamChecker class as follows −
StreamChecker(words) − This is the constructor, this initializes the data structure with the given words.
StreamChecker(words) − This is the constructor, this initializes the data structure with the given words.
query(letter) − This returns true when for some k >= 1, the last k characters queried (in order from oldest to newest, including this letter just queried) spell one of the words in the given list.
query(letter) − This returns true when for some k >= 1, the last k characters queried (in order from oldest to newest, including this letter just queried) spell one of the words in the given list.
So, if the input is like word list = ["ce", "g", "lm"], then call query many times for [a,b,c,e,f,g,h,i,j,k,l,m], then the output will be true for e, g, m, and false for others.
To solve this, we will follow these steps −
Define a node structure, there is an array of 26 nodes, and isEnd flag
Define a node structure, there is an array of 26 nodes, and isEnd flag
initially isEnd is false, and the child array is filled with null.
initially isEnd is false, and the child array is filled with null.
Define a node head
Define a node head
Make an array of nodes waitList
Make an array of nodes waitList
Define a function insertNode(), this will take head, s,curr := headfor initialize i := 0, when i < size of s, update (increase i by 1), do−x := s[i]if child[x - 'a'] of curr is not-null, then −curr.child[x - 'a'] = create a new node Nodecurr := curr.child[x - 'a']isEnd of curr := true
Define a function insertNode(), this will take head, s,
curr := head
curr := head
for initialize i := 0, when i < size of s, update (increase i by 1), do−x := s[i]if child[x - 'a'] of curr is not-null, then −curr.child[x - 'a'] = create a new node Nodecurr := curr.child[x - 'a']
for initialize i := 0, when i < size of s, update (increase i by 1), do−
x := s[i]
x := s[i]
if child[x - 'a'] of curr is not-null, then −curr.child[x - 'a'] = create a new node Node
if child[x - 'a'] of curr is not-null, then −
curr.child[x - 'a'] = create a new node Node
curr.child[x - 'a'] = create a new node Node
curr := curr.child[x - 'a']
curr := curr.child[x - 'a']
isEnd of curr := true
isEnd of curr := true
From the initializer do thishead := create a new nodefor initialize i := 0, when i < size of words, update (increase i by 1), do −insertNode(head, words[i])curr := head
From the initializer do this
head := create a new node
head := create a new node
for initialize i := 0, when i < size of words, update (increase i by 1), do −insertNode(head, words[i])
for initialize i := 0, when i < size of words, update (increase i by 1), do −
insertNode(head, words[i])
insertNode(head, words[i])
curr := head
curr := head
Define a function query(), this will take x,make one array of nodes tempif head.child[x - 'a'], then −insert head at the end of waitListret := falsefor initialize i := 0, when i < size of waitList, update (increase i by 1), do −curr := waitList[i]if curr.child[x - 'a'], thencurr := child[x - 'a'] of currinsert curr at the end of tempret := ret OR isEnd of currswap(temp, waitList)return ret
Define a function query(), this will take x,
make one array of nodes temp
make one array of nodes temp
if head.child[x - 'a'], then −insert head at the end of waitList
if head.child[x - 'a'], then −
insert head at the end of waitList
insert head at the end of waitList
ret := false
ret := false
for initialize i := 0, when i < size of waitList, update (increase i by 1), do −curr := waitList[i]if curr.child[x - 'a'], thencurr := child[x - 'a'] of currinsert curr at the end of tempret := ret OR isEnd of curr
for initialize i := 0, when i < size of waitList, update (increase i by 1), do −
curr := waitList[i]
curr := waitList[i]
if curr.child[x - 'a'], thencurr := child[x - 'a'] of currinsert curr at the end of tempret := ret OR isEnd of curr
if curr.child[x - 'a'], then
curr := child[x - 'a'] of curr
curr := child[x - 'a'] of curr
insert curr at the end of temp
insert curr at the end of temp
ret := ret OR isEnd of curr
ret := ret OR isEnd of curr
swap(temp, waitList)
swap(temp, waitList)
return ret
return ret
Let us see the following implementation to get better understanding −
#include <bits/stdc++.h>
using namespace std;
struct Node {
   Node* child[26];
   bool isEnd;
   Node(){
      isEnd = false;
      for (int i = 0; i < 26; i++)
      child[i] = NULL;
   }
};
class StreamChecker {
   public:
   Node* head;
   vector<Node*> waitList;
   void insertNode(Node* head, string& s){
      Node* curr = head;
      for (int i = 0; i < s.size(); i++) {
         char x = s[i];
         if (!curr->child[x - 'a']) {
            curr->child[x - 'a'] = new Node();
         }
         curr = curr->child[x - 'a'];
      }
      curr->isEnd = true;
   }
   StreamChecker(vector<string>& words){
      head = new Node();
      for (int i = 0; i < words.size(); i++) {
         insertNode(head, words[i]);
      }
      Node* curr = head;
   }
   bool query(char x){
      vector<Node*> temp;
      if (head->child[x - 'a']) {
         waitList.push_back(head);
      }
      bool ret = false;
      for (int i = 0; i < waitList.size(); i++) {
         Node* curr = waitList[i];
         if (curr->child[x - 'a']) {
            curr = curr->child[x - 'a'];
            temp.push_back(curr);
            ret |= curr->isEnd;
         }
      }
      swap(temp, waitList);
      return ret;
   }
};
main(){
   vector<string> v = {"ce","g","lm"};
   StreamChecker ob(v);
   cout << (ob.query('a')) << endl;
   cout << (ob.query('b')) << endl;
   cout << (ob.query('c')) << endl;
   cout << (ob.query('e')) << endl;
   cout << (ob.query('f')) << endl;
   cout << (ob.query('g')) << endl;
   cout << (ob.query('h')) << endl;
   cout << (ob.query('i')) << endl;
   cout << (ob.query('j')) << endl;
   cout << (ob.query('k')) << endl;
   cout << (ob.query('l')) << endl;
   cout << (ob.query('m'));
}
"ce","g","lm", query(),
0 0 0 1 0 1 0 0 0 0 0 1