Concatenated Words in C++


Suppose we have a list of words. These words are distinct. We have to devise an algorithm that will find all concatenated words in the give list of words. A concatenated word is actually a string that is comprised entirely of at least two shorter words in the given array.

So if the words are like ["cow", "cows", "cowsgoatcows", "goat", "goatcowsgoat", "hippopotamuses", "deer", "deercowgoatcow"], then the output will be ["cowsgoatcows", "goatcowsgoat", "deercowgoatcow"]

To solve this, we will follow these steps −

  • Define a function isPresent(), this will take str, head, idx, an array dp,
  • if idx >= size of str, then −
    • return true
  • if dp[idx] is not equal to -1, then −
    • return dp[idx]
  • create a node curr := head
  • ok := false
  • for initialize i := idx, when i < size of str, update (increase i by 1), do −
    • x := str[i]
    • if not child[x] of curr, then −
      • Come out from the loop
    • Otherwise
      • curr := child[x] of curr
    • if isEnd of curr is true, then −
      • ok := ok OR isPresent(str, head, i + 1, dp)
  • return dp[idx] := ok
  • Define a function insertNode(), this will take head, s,
  • Create a node curr = head
  • for initialize i := 0, when i < size of s, update (increase i by 1), do −
    • x := s[i]
    • if not child[x] of curr, then −
      • child[x] of curr := create a new Node
    • curr := child[x] of curr
  • isEnd of curr := true
  • From the main method, do the following −
  • head := create a new Node
  • sort the array words based on the length of words
  • Define an array ret
  • for initialize i := 0, when i < size of words, update (increase i by 1), do −
    • curr := words[i]
    • if curr is same as "", then −
      • Ignore following part, skip to the next iteration
    • Define an array dp of same size of curr, fill this with -1
    • if call the function isPresent(curr, head, 0, dp) is non-zero, then −
      • insert curr at the end of ret
    • Otherwise
      • call the function insertNode(head, curr)
  • return ret

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
   cout << "[";
   for(int i = 0; i<v.size(); i++){
      cout << v[i] << ", ";
   }
   cout << "]"<<endl;
}
struct Node{
   bool isEnd;
   map <char, Node*> child;
   Node(){
      isEnd = false;
   }
};
class Solution {
public:
   bool isPresent(string str, Node* head, int idx, vector <int>& dp){
      if(idx >= str.size())return true;
      if(dp[idx] != -1)return dp[idx];
      Node* curr = head;
      bool ok = false;
      for(int i = idx; i < str.size(); i++){
         char x = str[i];
         if(!curr->child[x]){
            break;
         }else{
            curr = curr->child[x];
         }
         if(curr->isEnd){
            ok |= isPresent(str, head, i + 1, dp);
         }
      }
      return dp[idx] = ok;
   }
   static bool cmp(string s1, string s2){
      return s1.size() < s2.size();
   }
   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]){
            curr->child[x] = new Node();
         }
         curr = curr->child[x];
      }
      curr->isEnd = true;
   }
   vector<string> findAllConcatenatedWordsInADict(vector<string>& words) {
      Node* head = new Node();
      sort(words.begin(), words.end(), cmp);
      vector <string> ret;
      for(int i = 0; i < words.size(); i++){
         string curr = words[i];
         if(curr=="")continue;
         vector <int> dp(curr.size(), -1);
         if(isPresent(curr, head, 0, dp)){
            ret.push_back(curr);
         }else{
            insertNode(head, curr);
         }
      }
      return ret;
   }
};
main(){
   Solution ob;
   vector<string> v =    {"cow","cows","cowsgoatcows","goat","goatcowsgoat","hippopotamuses","deer","deercowgoatcow"};
   print_vector(ob.findAllConcatenatedWordsInADict(v));
}

Input

{"cow","cows","cowsgoatcows","goat","goatcowsgoat","hippopotamuses","deer","deercowgoatcow"}

Output

[cowsgoatcows, goatcowsgoat, deercowgoatcow, ]

Updated on: 01-Jun-2020

100 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements