Given a valid sentence without any spaces between the words and a dictionary of valid English words, find all possible ways to break the sentence into individual dictionary words.
Example:
Consider the following dictionary
{ i, like, sam, sung, samsung, mobile, ice,
and, cream, icecream, man, go, mango}
Input: "ilikesamsungmobile"
Output: i like sam sung mobile
i like samsung mobile
Input: "ilikeicecreamandmango"
Output: i like ice cream and man go
i like ice cream and mango
i like icecream and man go
i like icecream and mango
We have discussed a Dynamic Programming solution in the below post.
Dynamic Programming | Set 32 (Word Break Problem)
The Dynamic Programming solution only finds whether it is possible to break a word or not. Here we need to print all possible word breaks.
We start scanning the sentence from the left. As we find a valid word, we need to check whether the rest of the sentence can make valid words or not. Because in some situations the first found word from the left side can leave a remaining portion that is not further separable. So, in that case, we should come back and leave the currently found word and keep on searching for the next word. And this process is recursive because to find out whether the right portion is separable or not, we need the same logic. So we will use recursion and backtracking to solve this problem. To keep track of the found words we will use a stack. Whenever the right portion of the string does not make valid words, we pop the top string from the stack and continue finding.
Below is the implementation of the above idea:
C++
#include <iostream>
using namespace std;
int dictionaryContains(string &word)
{
string dictionary[] = { "mobile" , "samsung" , "sam" , "sung" ,
"man" , "mango" , "icecream" , "and" ,
"go" , "i" , "love" , "ice" , "cream" };
int n = sizeof (dictionary)/ sizeof (dictionary[0]);
for ( int i = 0; i < n; i++)
if (dictionary[i].compare(word) == 0)
return true ;
return false ;
}
void wordBreakUtil(string str, int size, string result);
void wordBreak(string str)
{
wordBreakUtil(str, str.size(), "" );
}
void wordBreakUtil(string str, int n, string result)
{
for ( int i=1; i<=n; i++)
{
string prefix = str.substr(0, i);
if (dictionaryContains(prefix))
{
if (i == n)
{
result += prefix;
cout << result << endl;
return ;
}
wordBreakUtil(str.substr(i, n-i), n-i,
result + prefix + " " );
}
}
}
int main()
{
cout << "First Test:\n" ;
wordBreak( "iloveicecreamandmango" );
cout << "\nSecond Test:\n" ;
wordBreak( "ilovesamsungmobile" );
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static void wordBreak( int n, List<String> dict, String s)
{
String ans= "" ;
wordBreakUtil(n, s, dict, ans);
}
static void wordBreakUtil( int n, String s, List<String> dict, String ans)
{
for ( int i = 1 ; i <= n; i++)
{
String prefix=s.substring( 0 , i);
if (dict.contains(prefix))
{
if (i == n)
{
ans += prefix;
System.out.println(ans);
return ;
}
wordBreakUtil(n - i, s.substring(i,n), dict, ans+prefix+ " " );
}
}
}
public static void main(String args[])
{
String str1 = "iloveicecreamandmango" ;
String str2 = "ilovesamsungmobile" ;
int n1 = str1.length();
int n2 = str2.length();
List <String> dict= Arrays.asList( "mobile" , "samsung" , "sam" , "sung" ,
"man" , "mango" , "icecream" , "and" ,
"go" , "i" , "love" , "ice" , "cream" );
System.out.println( "First Test:" );
wordBreak(n1,dict,str1);
System.out.println( "\nSecond Test:" );
wordBreak(n2,dict,str2);
}
}
|
Python3
def dictionaryContains(word):
dictionary = { "mobile" , "samsung" , "sam" , "sung" , "man" ,
"mango" , "icecream" , "and" , "go" , "i" , "love" , "ice" , "cream" }
return word in dictionary
def wordBreak(string):
wordBreakUtil(string, len (string), "")
def wordBreakUtil(string, n, result):
for i in range ( 1 , n + 1 ):
prefix = string[:i]
if dictionaryContains(prefix):
if i = = n:
result + = prefix
print (result)
return
wordBreakUtil(string[i:], n - i, result + prefix + " " )
if __name__ = = "__main__" :
print ( "First Test:" )
wordBreak( "iloveicecreamandmango" )
print ( "\nSecond Test:" )
wordBreak( "ilovesamsungmobile" )
|
C#
using System;
using System.Collections.Generic;
class GFG {
static void wordBreak( int n, List< string > dict, string s)
{
string ans= "" ;
wordBreakUtil(n, s, dict, ans);
}
static void wordBreakUtil( int n, string s, List< string > dict, string ans)
{
for ( int i = 1; i <= n; i++)
{
string prefix=s.Substring(0, i);
if (dict.Contains(prefix))
{
if (i == n)
{
ans += prefix;
Console.WriteLine(ans);
return ;
}
wordBreakUtil(n - i, s.Substring(i,n-i), dict, ans+prefix+ " " );
}
}
}
static void Main() {
string str1 = "iloveicecreamandmango" ;
string str2 = "ilovesamsungmobile" ;
int n1 = str1.Length;
int n2 = str2.Length;
List< string > dict= new List< string >( new string []{ "mobile" , "samsung" , "sam" , "sung" ,
"man" , "mango" , "icecream" , "and" ,
"go" , "i" , "love" , "ice" , "cream" });
Console.WriteLine( "First Test:" );
wordBreak(n1,dict,str1);
Console.WriteLine();
Console.WriteLine( "Second Test:" );
wordBreak(n2,dict,str2);
}
}
|
Javascript
<script>
function wordBreak(n,dict,s)
{
let ans= "" ;
wordBreakUtil(n, s, dict, ans);
}
function wordBreakUtil(n,s,dict,ans)
{
for (let i = 1; i <= n; i++)
{
let prefix=s.substring(0, i);
if (dict.includes(prefix))
{
if (i == n)
{
ans += prefix;
document.write(ans+ "<br>" );
return ;
}
wordBreakUtil(n - i, s.substring(i,n), dict, ans+prefix+ " " );
}
}
}
let str1 = "iloveicecreamandmango" ;
let str2 = "ilovesamsungmobile" ;
let n1 = str1.length;
let n2 = str2.length;
let dict= [ "mobile" , "samsung" , "sam" , "sung" ,
"man" , "mango" , "icecream" , "and" ,
"go" , "i" , "love" , "ice" , "cream" ];
document.write( "First Test:<br>" );
wordBreak(n1,dict,str1);
document.write( "<br>Second Test:<br>" );
wordBreak(n2,dict,str2);
</script>
|
Output
First Test:
i love ice cream and man go
i love ice cream and mango
i love icecream and man go
i love icecream and mango
Second Test:
i love sam sung mobile
i love samsung mobile
Complexities:
- Time Complexity: O(2n). Because there are 2n combinations in The Worst Case.
- Auxiliary Space: O(n2). Because of the Recursive Stack of wordBreakUtil(…) function in The Worst Case.
Where n is the length of the input string.
If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
06 Jul, 2022
Like Article
Save Article