Print all possible combinations of words from Dictionary using Trie - GeeksforGeeks

13 Feb, 2020
Given an array of strings arr[], for every string in the array, print all possible combinations of strings that can be concatenated to make that word.
Examples:
Input: arr[] = ["sam", "sung", "samsung"]
Output:
sam: 
    sam
sung: 
    sung
samsung: 
    sam sung
    samsung
String 'samsung' can be formed using two different 
strings from the array i.e. 'sam' and 'sung' whereas 
'samsung' itself is also a string in the array.

Input: arr[] = ["ice", "cream", "icecream"]
Output:
ice: 
    ice
cream: 
    cream
icecream: 
    ice cream
    icecream

Approach:
Add all the given strings into trie.
Process every prefix character by character and check if it forms a word from trie by searching.
If the prefix is present in the trie then add it to the result and proceed further with the remaining suffix in the string.
Once it reaches the end of the string, print all the combinations found.
Below is the implementation of the above approach:
CPP
Java
C#
// C++ implementation of the approach  #include <bits/stdc++.h>using namespace std;  const int ALPHABET_SIZE = 26;  // Trie nodestruct TrieNode {    struct TrieNode* children[ALPHABET_SIZE];      // isEndOfWord is true if node    // represents the end of the word    bool isEndOfWord;};  // Returns new trie nodestruct TrieNode*getNode(void){    struct TrieNode* pNode = new TrieNode;      pNode->isEndOfWord = false;      for (int i = 0; i < ALPHABET_SIZE; i++)        pNode->children[i] = NULL;      return pNode;}  // If not present, inserts key into trie// If the key is prefix of trie node,// marks the node as leaf nodevoid insert(struct TrieNode* root, string key){    struct TrieNode* pCrawl = root;      for (int i = 0; i < key.length(); i++) {        int index = key[i] - 'a';        if (!pCrawl->children[index])            pCrawl->children[index] = getNode();          pCrawl = pCrawl->children[index];    }      // Mark node as leaf    pCrawl->isEndOfWord = true;}  // Returns true if the key is present in the triebool search(struct TrieNode* root, string key){    struct TrieNode* pCrawl = root;      for (int i = 0; i < key.length(); i++) {        int index = key[i] - 'a';        if (!pCrawl->children[index])            return false;          pCrawl = pCrawl->children[index];    }      return (pCrawl != NULL && pCrawl->isEndOfWord);}  // Result stores the current prefix with// spaces between wordsvoid wordBreakAll(TrieNode* root,                  string word, int n, string result){    // Process all prefixes one by one    for (int i = 1; i <= n; i++) {          // Extract substring from 0 to i in prefix        string prefix = word.substr(0, i);          // If trie conatins this prefix then check        // for the remaining string.        // Otherwise ignore this prefix        if (search(root, prefix)) {              // If no more elements are there then print            if (i == n) {                  // Add this element to the previous prefix                result += prefix;                  // If(result == word) then return                // If you don't want to print last word                cout << "\t" << result << endl;                return;            }            wordBreakAll(root, word.substr(i, n - i), n - i,                         result + prefix + " ");        }    }}  // Driver codeint main(){    struct TrieNode* root = getNode();      string dictionary[] = {        "sam", "sung",        "samsung"    };    int n = sizeof(dictionary) / sizeof(string);      for (int i = 0; i < n; i++) {        insert(root, dictionary[i]);    }      for (int i = 0; i < n; i++) {        cout << dictionary[i] << ": \n";        wordBreakAll(root, dictionary[i],                     dictionary[i].length(), "");    }      return 0;}
// Java implementation of the approachclass GFG{  static int ALPHABET_SIZE = 26;  // Trie nodestatic class TrieNode{    TrieNode []children =     new TrieNode[ALPHABET_SIZE];      // isEndOfWord is true if node    // represents the end of the word    boolean isEndOfWord;      public TrieNode()    {        super();    }      };  // Returns new trie nodestatic TrieNode getNode(){    TrieNode pNode = new TrieNode();      pNode.isEndOfWord = false;      for (int i = 0; i < ALPHABET_SIZE; i++)        pNode.children[i] = null;      return pNode;}  // If not present, inserts key into trie// If the key is prefix of trie node,// marks the node as leaf nodestatic void insert(TrieNode root, String key){    TrieNode pCrawl = root;      for (int i = 0; i < key.length(); i++)    {        int index = key.charAt(i) - 'a';        if (pCrawl.children[index] == null)            pCrawl.children[index] = getNode();          pCrawl = pCrawl.children[index];    }      // Mark node as leaf    pCrawl.isEndOfWord = true;}  // Returns true if the key is present in the triestatic boolean search(TrieNode root, String key){    TrieNode pCrawl = root;      for (int i = 0; i < key.length(); i++)    {        int index = key.charAt(i) - 'a';        if (pCrawl.children[index] == null)            return false;          pCrawl = pCrawl.children[index];    }      return (pCrawl != null && pCrawl.isEndOfWord);}  // Result stores the current prefix with// spaces between wordsstatic void wordBreakAll(TrieNode root,                String word, int n, String result){    // Process all prefixes one by one    for (int i = 1; i <= n; i++)     {          // Extract subString from 0 to i in prefix        String prefix = word.substring(0, i);          // If trie conatins this prefix then check        // for the remaining String.        // Otherwise ignore this prefix        if (search(root, prefix))        {              // If no more elements are there then print            if (i == n)             {                  // Add this element to the previous prefix                result += prefix;                  // If(result == word) then return                // If you don't want to print last word                System.out.print("\t" + result +"\n");                return;            }            wordBreakAll(root, word.substring(i, n), n - i,                        result + prefix + " ");        }    }}  // Driver codepublic static void main(String[] args){    new TrieNode();    TrieNode root = getNode();      String dictionary[] = {"sam", "sung",                            "samsung"};    int n = dictionary.length;      for (int i = 0; i < n; i++)    {        insert(root, dictionary[i]);    }      for (int i = 0; i < n; i++)    {        System.out.print(dictionary[i]+ ": \n");        wordBreakAll(root, dictionary[i],                    dictionary[i].length(), "");    }}}  // This code is contributed by PrinciRaj1992
// C# implementation of the approachusing System;  class GFG{  static int ALPHABET_SIZE = 26;  // Trie nodeclass TrieNode{    public TrieNode []children =     new TrieNode[ALPHABET_SIZE];      // isEndOfWord is true if node    // represents the end of the word    public bool isEndOfWord;      public TrieNode()    {    }      };  // Returns new trie nodestatic TrieNode getNode(){    TrieNode pNode = new TrieNode();      pNode.isEndOfWord = false;      for (int i = 0; i < ALPHABET_SIZE; i++)        pNode.children[i] = null;      return pNode;}  // If not present, inserts key into trie// If the key is prefix of trie node,// marks the node as leaf nodestatic void insert(TrieNode root, String key){    TrieNode pCrawl = root;      for (int i = 0; i < key.Length; i++)    {        int index = key[i] - 'a';        if (pCrawl.children[index] == null)            pCrawl.children[index] = getNode();          pCrawl = pCrawl.children[index];    }      // Mark node as leaf    pCrawl.isEndOfWord = true;}  // Returns true if the key is present in the triestatic bool search(TrieNode root, String key){    TrieNode pCrawl = root;      for (int i = 0; i < key.Length; i++)    {        int index = key[i] - 'a';        if (pCrawl.children[index] == null)            return false;          pCrawl = pCrawl.children[index];    }      return (pCrawl != null && pCrawl.isEndOfWord);}  // Result stores the current prefix with// spaces between wordsstatic void wordBreakAll(TrieNode root,                String word, int n, String result){    // Process all prefixes one by one    for (int i = 1; i <= n; i++)     {          // Extract subString from 0 to i in prefix        String prefix = word.Substring(0, i);          // If trie conatins this prefix then check        // for the remaining String.        // Otherwise ignore this prefix        if (search(root, prefix))        {              // If no more elements are there then print            if (i == n)             {                  // Add this element to the previous prefix                result += prefix;                  // If(result == word) then return                // If you don't want to print last word                Console.Write("\t" + result +"\n");                return;            }            wordBreakAll(root, word.Substring(i, n - i), n - i,                        result + prefix + " ");        }    }}  // Driver codepublic static void Main(String[] args){    new TrieNode();    TrieNode root = getNode();      String []dictionary = {"sam", "sung",                            "samsung"};    int n = dictionary.Length;      for (int i = 0; i < n; i++)    {        insert(root, dictionary[i]);    }      for (int i = 0; i < n; i++)    {        Console.Write(dictionary[i]+ ": \n");        wordBreakAll(root, dictionary[i],                    dictionary[i].Length, "");    }}}  // This code is contributed by PrinciRaj1992
sam: 
    sam
sung: 
    sung
samsung: 
    sam sung
    samsung

princiraj1992
Technical Scripter 2019
Trie
Arrays
Backtracking
Strings
Technical Scripter
Arrays
Strings
Backtracking
Trie
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Count pairs with given sum
Chocolate Distribution Problem
Window Sliding Technique
Reversal algorithm for array rotation
Next Greater Element
N Queen Problem | Backtracking-3
Write a program to print all permutations of a given string
Backtracking | Introduction
Rat in a Maze | Backtracking-2
The Knight's tour problem | Backtracking-1