
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
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
#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, ]
Advertisements