Word Break Problem | DP-32 | Set – 2

22 Jun, 2022
Given a non-empty sequence S and a dictionary dict[] containing a list of non-empty words, print all possible ways to break the sentence in individual dictionary words.Examples:  
Input: S = “catsanddog” dict[] = {“cat”, “cats”, “and”, “sand”, “dog”} Output: “cats and dog” “cat sand dog”Input: S = “pineapplepenapple” dict[] = {“apple”, “pen”, “applepen”, “pine”, “pineapple”} Output: “pine apple pen apple” “pineapple pen apple” “pine applepen apple”  
 
A similar problem to this is discussed in this article, where the task is to check that is there any solution such that the sequence can be broken into the dictionary words.Approach: The idea is to check for every substring starting from any position I , such that it ends at the length of the string which is present in the dictionary then simply recurse for the substring [0, I]. Meanwhile, store the overlapping subproblems for each substring to avoid the computation of the subproblem again. Overlapping subproblems can be shown as follows –  
Below is the implementation of the above approach:  
C++
Java
Python3
Javascript
// C++ implementation to break// a sequence into the words of// the dictionary #include <bits/stdc++.h> using namespace std; // Unordered_map used for storing// the sentences the key string// can be broken intounordered_map<string,            vector<string> > mp; // Unordered_set used// to store the dictionary.unordered_set<string> dict; // Utility function used for// printing the obtained resultvoid printResult(vector<string> A){    for (int i = 0; i < A.size(); i++)        cout << A[i] << '\n';} // Utility function for// appending new words// to already existing stringsvector<string> combine(     vector<string> prev, string word){         // Loop to find the append string    // which can be broken into    for (int i = 0; i < prev.size(); i++) {        prev[i] += " " + word;    }    return prev;} // Utility function for word Breakvector<string> wordBreakUtil(string s){      // Condition to check if the    // subproblem is already computed    if (mp.find(s) != mp.end())        return mp[s];    vector<string> res;         // If the whole word is a dictionary    // word then directly append into    // the result array for the string    if (dict.find(s) != dict.end())        res.push_back(s);         // Loop to iterate over the substring    for (int i = 1; i < s.length(); i++) {        string word = s.substr(i);                 // If the substring is present into        // the dictionary then recurse for        // other substring of the string        if (dict.find(word) != dict.end()) {            string rem = s.substr(0, i);            vector<string> prev =             combine(wordBreakUtil(rem), word);            res.insert(res.end(),                 prev.begin(), prev.end());        }    }         // Store the subproblem    // into the map    mp[s] = res;    return res;} // Master wordBreak function converts// the string vector to unordered_setvector<string> wordBreak(string s,             vector<string>& wordDict){    // Clear the previous stored data    mp.clear();    dict.clear();    dict.insert(wordDict.begin(), wordDict.end());    return wordBreakUtil(s);} // Driver Codeint main(){    vector<string> wordDict1 = {        "cat", "cats", "and", "sand", "dog" };    printResult(wordBreak("catsanddog", wordDict1));    return 0;}
import java.util.*;import java.io.*; // Java program for the above approachclass GFG{   // Unordered_map used for storing  // the sentences the key String  // can be broken into  static TreeMap<String, ArrayList<String>> mp =    new TreeMap<String, ArrayList<String>>();   // Unordered_set used  // to store the dictionary.  static TreeSet<String> dict = new TreeSet<String>();   // Utility function used for  // printing the obtained result  static void printResult(ArrayList<String> A)  {    for (int i = 0 ; i < A.size() ; i++){      System.out.println(A.get(i));    }  }   // Utility function for  // appending new words  // to already existing strings  static ArrayList<String> combine(ArrayList<String> prev, String word){     // Loop to find the append String    // which can be broken into    for (int i = 0 ; i < prev.size() ; i++) {      prev.set(i, prev.get(i) + " " + word);    }    return prev;  }   // Utility function for word Break  static ArrayList<String> wordBreakUtil(String s)  {     // Condition to check if the    // subproblem is already computed    if (mp.containsKey(s)){      return mp.get(s);    }    ArrayList<String> res = new ArrayList<String>();     // If the whole word is a dictionary    // word then directly append into    // the result array for the String    if (dict.contains(s))      res.add(s);     // Loop to iterate over the substring    for (int i = 1 ; i < s.length() ; i++) {      String word = s.substring(i);       // If the substring is present into      // the dictionary then recurse for      // other substring of the String      if (dict.contains(word)) {        String rem = s.substring(0, i);        ArrayList<String> prev =  combine(wordBreakUtil(rem), word);        for(int j = 0 ; j < prev.size() ; j++){          res.add(prev.get(j));        }      }    }     // Store the subproblem    // into the map    mp.put(s, res);    return res;  }   // Master wordBreak function converts  // the String vector to unordered_set  static ArrayList<String> wordBreak(String s, ArrayList<String> wordDict)  {    // Clear the previous stored data    mp.clear();    dict.clear();    dict.addAll(wordDict);    return wordBreakUtil(s);  }   // Driver Code  public static void main(String args[])  {    ArrayList<String> wordDict1 = new ArrayList<String>(      List.of("cat", "cats", "and", "sand", "dog")    );    printResult(wordBreak("catsanddog", wordDict1));  }} // This code is contributed by subhamgoyal2014.
# Python3 implementation to break# a sequence into the words of# the dictionary  # Unordered_map used for storing# the sentences the key string# can be broken intomp = dict()  # Unordered_set used# to store the dictionary.dict_t = set()  # Utility function used for# printing the obtained resultdef printResult(A):     for i in range(len(A)):        print(A[i])  # Utility function for# appending new words# to already existing stringsdef combine( prev, word):          # Loop to find the append string    # which can be broken into    for i in range(len(prev)):             prev[i] += " " + word;         return prev; # Utility function for word Breakdef wordBreakUtil(s):     # Condition to check if the    # subproblem is already computed    if (s in mp):        return mp[s];         res = []          # If the whole word is a dictionary    # word then directly append into    # the result array for the string    if (s in dict_t):        res.append(s);          # Loop to iterate over the substring    for i in range(1, len(s)):                 word = s[i:];                  # If the substring is present into        # the dictionary then recurse for        # other substring of the string        if (word in dict_t):                         rem = s[:i]            prev = combine(wordBreakUtil(rem), word);            for i in prev:                res.append(i)          # Store the subproblem    # into the map    #res is an reference so we need to assign an reference to something if its keep on changing    #res values changes after it start going through combine method    #you can check if you had a doubt so here we just clone res    x=[]    for i in res:      x.append(i)    mp[s] = x;    return res;  # Master wordBreak function converts# the string vector to unordered_setdef wordBreak(s,  wordDict):     # Clear the previous stored data    mp.clear();    dict_t.clear();    for i in wordDict:        dict_t.add(i)    return wordBreakUtil(s); # Driver Codeif __name__=='__main__':     wordDict1 = ["cat", "cats", "and", "sand", "dog" ]    printResult(wordBreak("catsanddog", wordDict1)); # This code is contributed by rutvik_56
<script> // JavaScript implementation to break// a sequence into the words of// the dictionary // Unordered_map used for storing// the sentences the key string// can be broken intolet mp = new Map() // Unordered_set used// to store the dictionary.let dict_t = new Set() // Utility function used for// printing the obtained resultfunction printResult(A){     for(let i=0;i<A.length;i++)        document.write(A[i],"</br>")}// Utility function for// pushing new words// to already existing stringsfunction combine(prev, word){         // Loop to find the push string    // which can be broken into    for (let i=0;i<prev.length;i++)             prev[i] += " " + word;         return prev;}// Utility function for word Breakfunction wordBreakUtil(s){     // Condition to check if the    // subproblem is already computed    if (mp.has(s))        return mp.get(s)         let res = []         // If the whole word is a dictionary    // word then directly push into    // the result array for the string    if (dict_t.has(s))        res.push(s);         // Loop to iterate over the substring    for(let i=1;i<s.length;i++){                 let word = s.substring(i,)                 // If the substring is present into        // the dictionary then recurse for        // other substring of the string        if (dict_t.has(word)){                         let rem = s.substring(0,i)            let prev = combine(wordBreakUtil(rem), word);            for(let i of prev)                res.push(i)        }    }         // Store the subproblem    // into the map    // res is an reference so we need to assign an reference to something if its keep on changing    // res values changes after it start going through combine method    // you can check if you had a doubt so here we just clone res    let x=[]    for(let i of res)        x.push(i)    mp.set(s, x)    return res} // Master wordBreak function converts// the string vector to unordered_setfunction wordBreak(s, wordDict){     // Clear the previous stored data    mp.clear();    dict_t.clear();    for(let i of wordDict)        dict_t.add(i)    return wordBreakUtil(s);} // Driver Code let wordDict1 = ["cat", "cats", "and", "sand", "dog" ];printResult(wordBreak("catsanddog", wordDict1)); // This code is contributed by shinjanpatra </script>
cat sand dog
cats and dog
 
Time Complexity: O(2^N), where N is the length of the given string.Auxiliary Space: O(S + N). where S is the sum of all characters of wordDict1.
rutvik_56
purnaanrup100
sumitgumber28
simmytarika5
pankajsharmagfg
shinjanpatra
subhamgoyal2014
Algorithms
Dynamic Programming
Recursion
Dynamic Programming
Recursion
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
DSA Sheet by Love Babbar
SDE SHEET - A Complete Guide for SDE Preparation
What is Hashing | A Complete Tutorial
Find if there is a path between two vertices in an undirected graph
Understanding Time Complexity with Simple Examples
Largest Sum Contiguous Subarray
Program for Fibonacci numbers
0-1 Knapsack Problem | DP-10
Subset Sum Problem | DP-25
Longest Palindromic Substring | Set 1