Add and Search Word - Data structure design in C++


Suppose we have to design a data structure that supports the following two operations −

  • addWord(word)

  • search(word)

The search(word) method can search a literal word or a regular expression string containing only letters a-z or .. A . means it can represent any one letter. So for example, if we add some words like “bad”, “dad”, “mad”, then search for search(“pad”) → false, search(“bad”) → true, search(“.ad”) → true and search(“b..”) → true

To solve this, we will follow these steps −

  • There are some methods, initially define insertNode(), this will take the head reference and the string s, this will work as follows −

  • curr := head, n := size of s

  • for i in range 0 to n – 1

    • x := s[i]

    • if child[x] of curr is not null, then child[x] of curr := new node

    • curr := child[x] of curr

  • set isEnd of curr as true

  • From the addWord(), call this insertNode() method

  • Define another method called check(), this will take curr, string s, and index. Initially index is 0. This will work as follows −

  • if index = size of s, then return isEnd of curr

  • set ok := true

  • if s[index] is dot, then

    • for i in range 0 to 25

      • x := ASCII of ‘a’ + i

      • if child[x] of curr AND check(child[x] of curr, s, index + 1) is true, then return true.

  • otherwise

    • x := s[index]

    • if child[x] of curr AND check(child[x] of curr, s, index + 1) is true, then return true.

  • return false

  • From the search method, set curr := head and return check(curr, word, 0)

Example (C++)

Let us see the following implementation to get a better understanding −

 Live Demo

#include <bits/stdc++.h>
using namespace std;
struct Node{
   bool isEnd;
   map <char, Node*> child;
   Node(){
      isEnd = false;
   }
};
class WordDictionary {
   public:
   Node* head;
   WordDictionary() {
      head = new Node();
   }
   void insertNode(Node* head, string s){
      Node* curr = head;
      int n = s.size();
      for(int i = 0; i < n; i++){
         char x = s[i];
         if(!curr->child[x]){
            curr->child[x] = new Node();
         }
         curr = curr->child[x];
      }
      curr->isEnd = true;
   }
   void addWord(string word) {
      insertNode(head, word);
   }
   bool check(Node* curr, string s, int idx = 0){
      if(idx == s.size()) return curr->isEnd;
         bool ok = false;
      if(s[idx] == '.'){
         for(int i = 0; i < 26; i++){
            char x = 'a' + i;
            if(curr->child[x] && check(curr->child[x], s, idx + 1))return true;
         }
      } else {
         char x = s[idx];
         if(curr->child[x] && check(curr->child[x], s, idx + 1))return true;
      }
      return false;
   }
   bool search(string word) {
      Node* curr = head;
      return check(curr, word);
   }
};
main(){
   WordDictionary ob;
   ob.addWord("bad");
   ob.addWord("dad");
   ob.addWord("mad");
   cout << (ob.search("pad")) << endl;
   cout << (ob.search("bad")) << endl;
   cout << (ob.search(".ad")) << endl;
   cout << (ob.search("b..")) << endl;
}

Input

Initialize the WordDictionary, then call the addWord() methods ans search methods. 
See in the main() function

Output

0
1
1
1

Updated on: 29-Apr-2020

361 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements