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.

  • 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

  • initially isEnd is false, and the child array is filled with null.

  • Define a node head

  • Make an array of nodes waitList

  • Define a function insertNode(), this will take head, s,

    • 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 Node

      • curr := curr.child[x - 'a']

    • isEnd of curr := true

  • From the initializer do this

    • head := create a new node

    • for initialize i := 0, when i < size of words, update (increase i by 1), do −

      • insertNode(head, words[i])

    • curr := head

  • Define a function query(), this will take x,

    • make one array of nodes temp

    • if head.child[x - 'a'], then −

      • insert head at the end of waitList

    • 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'], then

        • curr := child[x - 'a'] of curr

        • insert curr at the end of temp

        • ret := ret OR isEnd of curr

    • swap(temp, waitList)

    • return ret

Let us see the following implementation to get better understanding −

Example

#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')); }

Input

"ce","g","lm", query(),

Output

0 0 0 1 0 1 0 0 0 0 0 1
Updated on: 2020-06-04T10:58:38+05:30

612 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements