# Concatenated Words in C++

C++Server Side ProgrammingProgramming

#### C in Depth: The Complete C Programming Guide for Beginners

45 Lectures 4.5 hours

#### Practical C++: Learn C++ Basics Step by Step

Most Popular

50 Lectures 4.5 hours

#### Master C and Embedded C Programming- Learn as you go

66 Lectures 5.5 hours

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{
}
}
return ret;
}
};
main(){
Solution ob;
vector<string> v =    {"cow","cows","cowsgoatcows","goat","goatcowsgoat","hippopotamuses","deer","deercowgoatcow"};
}
{"cow","cows","cowsgoatcows","goat","goatcowsgoat","hippopotamuses","deer","deercowgoatcow"}
[cowsgoatcows, goatcowsgoat, deercowgoatcow, ]