Given a string array of M words and a dictionary of N words. The task is to check if the given string of words can be formed from words present in the dictionary.
Examples:
dict[] = { find, a, geeks, all, for, on, geeks, answers, inter }
Input: str[] = { “find”, “all”, “answers”, “on”, “geeks”, “for”, “geeks” };
Output: YES
all words of str[] are present in the dictionary so the output is YESInput: str = {“find”, “a”, “geek”}
Output: NO
In str[], “find” and “a” were present in the dictionary but “geek” is not present in the dictionary so the output is NO
A naive Approach will be to match all words of the input sentence separately with each of the words in the dictionary and maintain a count of the number of occurrence of all words in the dictionary. So if the number of words in dictionary be n and no of words in the sentence be m this algorithm will take O(M*N) time.
A better approach will be to use the modified version of the advanced data structure Trie the time complexity can be reduced to O(M * t) where t is the length of longest word in the dictionary which is lesser than n. So here a modification has been done to the trie node such that the isEnd variable is now an integer storing the count of occurrence of the word ending on this node. Also, the search function has been modified to find a word in the trie and once found decrease the count of isEnd of that node so that for multiple occurrences of a word in a sentence each is matched with a separate occurrence of that word in the dictionary.
Below is the illustration of the above approach:
// C++ program to check if a sentence // can be formed from a given set of words. #include <bits/stdc++.h> using namespace std;
const int ALPHABET_SIZE = 26;
// here isEnd is an integer that will store // count of words ending at that node struct trieNode {
trieNode* t[ALPHABET_SIZE];
int isEnd;
}; // utility function to create a new node trieNode* getNode() { trieNode* temp = new (trieNode);
// Initialize new node with null
for ( int i = 0; i < ALPHABET_SIZE; i++)
temp->t[i] = NULL;
temp->isEnd = 0;
return temp;
} // Function to insert new words in trie void insert(trieNode* root, string key)
{ trieNode* trail;
trail = root;
// Iterate for the length of a word
for ( int i = 0; i < key.length(); i++) {
// If the next key does not contains the character
if (trail->t[key[i] - 'a' ] == NULL) {
trieNode* temp;
temp = getNode();
trail->t[key[i] - 'a' ] = temp;
}
trail = trail->t[key[i] - 'a' ];
}
// isEnd is increment so not only the word but its count is also stored
(trail->isEnd)++;
} // Search function to find a word of a sentence bool search_mod(trieNode* root, string word)
{ trieNode* trail;
trail = root;
// Iterate for the complete length of the word
for ( int i = 0; i < word.length(); i++) {
// If the character is not present then word
// is also not present
if (trail->t[word[i] - 'a' ] == NULL)
return false ;
// If present move to next character in Trie
trail = trail->t[word[i] - 'a' ];
}
// If word foundthen decrement count of the word
if ((trail->isEnd) > 0 && trail != NULL) {
// if the word is found decrement isEnd showing one
// occurrence of this word is already taken so
(trail->isEnd)--;
return true ;
}
else
return false ;
} // Function to check if string can be // formed from the sentence void checkPossibility(string sentence[], int m, trieNode* root)
{ int flag = 1;
// Iterate for all words in the string
for ( int i = 0; i < m; i++) {
if (search_mod(root, sentence[i]) == false ) {
// if a word is not found in a string then the
// sentence cannot be made from this dictionary of words
cout << "NO" ;
return ;
}
}
// If possible
cout << "YES" ;
} // Function to insert all the words of dictionary in the Trie void insertToTrie(string dictionary[], int n,
trieNode* root)
{ for ( int i = 0; i < n; i++)
insert(root, dictionary[i]);
} // Driver Code int main()
{ trieNode* root;
root = getNode();
// Dictionary of words
string dictionary[] = { "find" , "a" , "geeks" ,
"all" , "for" , "on" ,
"geeks" , "answers" , "inter" };
int N = sizeof (dictionary) / sizeof (dictionary[0]);
// Calling Function to insert words of dictionary to tree
insertToTrie(dictionary, N, root);
// String to be checked
string sentence[] = { "find" , "all" , "answers" , "on" ,
"geeks" , "for" , "geeks" };
int M = sizeof (sentence) / sizeof (sentence[0]);
// Function call to check possibility
checkPossibility(sentence, M, root);
return 0;
} |
// Java program to check if a sentence // can be formed from a given set of words. import java.util.*;
public class Trie {
// Trie Node class
static class TrieNode {
TrieNode[] t;
int isEnd;
// Constructor
TrieNode() {
t = new TrieNode[ 26 ];
isEnd = 0 ;
}
}
// Root of Trie
static TrieNode root;
// Constructor
Trie() {
root = new TrieNode();
}
// Function to insert a word
public static void insert(String key)
{
TrieNode trail = root;
int len = key.length();
char [] ch = key.toCharArray();
for ( int i = 0 ; i < len; i++) {
int index = ch[i] - 'a' ;
if (trail.t[index] == null ) {
trail.t[index] = new TrieNode();
}
trail = trail.t[index];
}
trail.isEnd++;
}
// Function to search a word
public static boolean search_mod(String key)
{
TrieNode trail = root;
int len = key.length();
char [] ch = key.toCharArray();
for ( int i = 0 ; i < len; i++) {
int index = ch[i] - 'a' ;
if (trail.t[index] == null )
return false ;
trail = trail.t[index];
}
if (trail.isEnd > 0 && trail != null ) {
trail.isEnd--;
return true ;
}
else
return false ;
}
// Function to check if string can be
// formed from the sentence
public static void checkPossibility(String[] sentence,
int m, TrieNode root)
{
int flag = 1 ;
for ( int i = 0 ; i < m; i++) {
if (search_mod(sentence[i]) == false ) {
System.out.println( "NO" );
return ;
}
}
System.out.println( "YES" );
}
// Driver Code
public static void main(String[] args)
{
// Dictionary of words
String dictionary[] = { "find" , "a" , "geeks" ,
"all" , "for" , "on" ,
"geeks" , "answers" , "inter" };
int N = dictionary.length;
Trie trie = new Trie();
for ( int i = 0 ; i < N; i++)
insert(dictionary[i]);
String sentence[] = { "find" , "all" , "answers" , "on" ,
"geeks" , "for" , "geeks" };
int M = sentence.length;
checkPossibility(sentence, M, root);
}
} |
# Python3 program to check if a sentence # can be formed from a given set of words. #include <bits/stdc++.h> ALPHABET_SIZE = 26 ;
# here isEnd is an integer that will store # count of words ending at that node class trieNode:
def __init__( self ):
self .t = [ None for i in range (ALPHABET_SIZE)]
self .isEnd = 0
# utility function to create a new node def getNode():
temp = trieNode()
return temp;
# Function to insert new words in trie def insert(root, key):
trail = None
trail = root;
# Iterate for the length of a word
for i in range ( len (key)):
# If the next key does not contains the character
if (trail.t[ ord (key[i]) - ord ( 'a' )] = = None ):
temp = None
temp = getNode();
trail.t[ ord (key[i]) - ord ( 'a' )] = temp;
trail = trail.t[ ord (key[i]) - ord ( 'a' )];
# isEnd is increment so not only
# the word but its count is also stored
(trail.isEnd) + = 1
# Search function to find a word of a sentence def search_mod(root, word):
trail = root;
# Iterate for the complete length of the word
for i in range ( len (word)):
# If the character is not present then word
# is also not present
if (trail.t[ ord (word[i]) - ord ( 'a' )] = = None ):
return False ;
# If present move to next character in Trie
trail = trail.t[ ord (word[i]) - ord ( 'a' )];
# If word found then decrement count of the word
if ((trail.isEnd) > 0 and trail ! = None ):
# if the word is found decrement isEnd showing one
# occurrence of this word is already taken so
(trail.isEnd) - = 1
return True ;
else :
return False ;
# Function to check if string can be # formed from the sentence def checkPossibility(sentence, m, root):
flag = 1 ;
# Iterate for all words in the string
for i in range (m):
if (search_mod(root, sentence[i]) = = False ):
# if a word is not found in a string then the
# sentence cannot be made from this dictionary of words
print ( 'NO' , end = '')
return ;
# If possible
print ( 'YES' )
# Function to insert all the words of dict in the Trie def insertToTrie(dictionary, n, root):
for i in range (n):
insert(root, dictionary[i]);
# Driver Code if __name__ = = '__main__' :
root = getNode();
# Dictionary of words
dictionary = [ "find" , "a" , "geeks" ,
"all" , "for" , "on" ,
"geeks" , "answers" , "inter" ]
N = len (dictionary)
# Calling Function to insert words of dictionary to tree
insertToTrie(dictionary, N, root);
# String to be checked
sentence = [ "find" , "all" , "answers" , "on" ,
"geeks" , "for" , "geeks" ]
M = len (sentence)
# Function call to check possibility
checkPossibility(sentence, M, root);
# This code is contributed by pratham76 |
// C# program to check if a sentence // can be formed from a given set of words. using System;
using System.Collections.Generic;
// Trie Node class public class TrieNode
{ public TrieNode[] t;
public int isEnd;
// Constructor
public TrieNode()
{
t = new TrieNode[26];
isEnd = 0;
}
} public class Trie
{ // Root of Trie
public TrieNode root;
// Constructor
public Trie()
{
root = new TrieNode();
}
// Function to insert a word
public void Insert( string key)
{
TrieNode trail = root;
int len = key.Length;
char [] ch = key.ToCharArray();
for ( int i = 0; i < len; i++)
{
int index = ch[i] - 'a' ;
if (trail.t[index] == null )
{
trail.t[index] = new TrieNode();
}
trail = trail.t[index];
}
trail.isEnd++;
}
// Function to search a word
public bool search_mod( string key)
{
TrieNode trail = root;
int len = key.Length;
char [] ch = key.ToCharArray();
for ( int i = 0; i < len; i++)
{
int index = ch[i] - 'a' ;
if (trail.t[index] == null )
{
return false ;
}
trail = trail.t[index];
}
if (trail.isEnd > 0 && trail != null )
{
trail.isEnd--;
return true ;
}
else
{
return false ;
}
}
// Function to check if string can be
// formed from the sentence
public void CheckPossibility( string [] sentence, int m, TrieNode root)
{
int flag = 1;
for ( int i = 0; i < m; i++)
{
if (!search_mod(sentence[i]))
{
Console.WriteLine( "NO" );
return ;
}
}
Console.WriteLine( "YES" );
}
} public class Program
{ // Driver Code
public static void Main( string [] args)
{
// Dictionary of words
string [] dictionary = { "find" , "a" , "geeks" , "all" , "for" , "on" , "geeks" , "answers" , "inter" };
int N = dictionary.Length;
Trie trie = new Trie();
for ( int i = 0; i < N; i++)
{
trie.Insert(dictionary[i]);
}
string [] sentence = { "find" , "all" , "answers" , "on" , "geeks" , "for" , "geeks" };
int M = sentence.Length;
trie.CheckPossibility(sentence, M, trie.root);
}
} // This code is contributed by Utkarsh Kumar. |
// Javascript code for the above approach // Define the alphabet size const ALPHABET_SIZE = 26; // Define a trie node structure to store words class TrieNode { constructor() {
this .t = new Array(ALPHABET_SIZE).fill( null );
this .isEnd = 0;
}
} // Function to insert new words in trie function insert(root, key) {
let trail = root;
// Iterate for the length of a word
for (let i = 0; i < key.length; i++) {
// If the next key does not contain the character
if (trail.t[key.charCodeAt(i) - 'a' .charCodeAt(0)] === null ) {
let temp = new TrieNode();
trail.t[key.charCodeAt(i) - 'a' .charCodeAt(0)] = temp;
}
trail = trail.t[key.charCodeAt(i) - 'a' .charCodeAt(0)];
}
// Increment isEnd so not only the word but its count is also stored
trail.isEnd++;
} // Search function to find a word of a sentence function searchMod(root, word) {
let trail = root;
// Iterate for the complete length of the word
for (let i = 0; i < word.length; i++) {
// If the character is not present then word
// is also not present
if (trail.t[word.charCodeAt(i) - 'a' .charCodeAt(0)] === null )
return false ;
// If present move to next character in Trie
trail = trail.t[word.charCodeAt(i) - 'a' .charCodeAt(0)];
}
// If word found then decrement count of the word
if (trail.isEnd > 0 && trail != null ) {
// if the word is found decrement isEnd showing one
// occurrence of this word is already taken so
trail.isEnd--;
return true ;
} else
return false ;
} // Function to check if string can be
// formed from the sentence
function checkPossibility(sentence, m, root) {
let flag = 1;
// Iterate for all words in the string
for (let i = 0; i < m; i++) {
if (searchMod(root, sentence[i]) === false ) {
// if a word is not found in a string then the
// sentence cannot be made from this dictionary of words
console.log( "NO" );
return ;
} } // If possible console.log( "YES" );
} // Function to insert all the words of dictionary in the Trie function insertToTrie(dictionary, n, root) {
for (let i = 0; i < n; i++)
insert(root, dictionary[i]);
}
// Driver Code
function main() {
let root = new TrieNode();
// Dictionary of words
let dictionary = [
"find" ,
"a" ,
"geeks" ,
"all" ,
"for" ,
"on" ,
"geeks" ,
"answers" ,
"inter" ,
];
let N = dictionary.length;
// Calling Function to insert words of dictionary to tree
insertToTrie(dictionary, N, root);
// String to be checked
let sentence = [
"find" ,
"all" ,
"answers" ,
"on" ,
"geeks" ,
"for" ,
"geeks" ,
];
let M = sentence.length;
// Function call to check possibility
checkPossibility(sentence, M, root);
} main(); // this code is contributed by bhardwajji |
YES
Time Complexity: O(M*N)
M is the length of the sentence and N is the number of words in the dictionary.
Space Complexity: O(N)
N is the number of words in the dictionary.
An efficient approach will be to use map. Keep the count of words in the map, iterate in the string and check if the word is present in the map. If present, then decrease the count of the word in the map. If it is not present, then it is not possible to make the given string from the given dictionary of words.
Below is the implementation of above approach :
// C++ program to check if a sentence // can be formed from a given set of words. #include <bits/stdc++.h> using namespace std;
// Function to check if the word // is in the dictionary or not bool match_words(string dictionary[], string sentence[],
int n, int m)
{ // map to store all words in
// dictionary with their count
unordered_map<string, int > mp;
// adding all words in map
for ( int i = 0; i < n; i++) {
mp[dictionary[i]]++;
}
// search in map for all
// words in the sentence
for ( int i = 0; i < m; i++) {
if (mp[sentence[i]])
mp[sentence[i]] -= 1;
else
return false ;
}
// all words of sentence are present
return true ;
} // Driver Code int main()
{ string dictionary[] = { "find" , "a" , "geeks" ,
"all" , "for" , "on" ,
"geeks" , "answers" , "inter" };
int n = sizeof (dictionary) / sizeof (dictionary[0]);
string sentence[] = { "find" , "all" , "answers" , "on" ,
"geeks" , "for" , "geeks" };
int m = sizeof (sentence) / sizeof (sentence[0]);
// Calling function to check if words are
// present in the dictionary or not
if (match_words(dictionary, sentence, n, m))
cout << "YES" ;
else
cout << "NO" ;
return 0;
} |
// Java program to check if a sentence // can be formed from a given set of words. import java.util.*;
class GFG
{ // Function to check if the word // is in the dictionary or not static boolean match_words(String dictionary[], String sentence[],
int n, int m)
{ // map to store all words in
// dictionary with their count
Map<String,Integer> mp = new HashMap<>();
// adding all words in map
for ( int i = 0 ; i < n; i++)
{
if (mp.containsKey(dictionary[i]))
{
mp.put(dictionary[i], mp.get(dictionary[i])+ 1 );
}
else
{
mp.put(dictionary[i], 1 );
}
}
// search in map for all
// words in the sentence
for ( int i = 0 ; i < m; i++)
{
if (mp.containsKey(sentence[i]))
mp.put(sentence[i],mp.get(sentence[i])- 1 );
else
return false ;
}
// all words of sentence are present
return true ;
} // Driver Code public static void main(String[] args)
{ String dictionary[] = { "find" , "a" , "geeks" ,
"all" , "for" , "on" ,
"geeks" , "answers" , "inter" };
int n = dictionary.length;
String sentence[] = { "find" , "all" , "answers" , "on" ,
"geeks" , "for" , "geeks" };
int m = sentence.length;
// Calling function to check if words are
// present in the dictionary or not
if (match_words(dictionary, sentence, n, m))
System.out.println( "YES" );
else
System.out.println( "NO" );
}
} // This code is contributed by Princi Singh |
# Python3 program to check if a sentence # can be formed from a given set of words. # Function to check if the word # is in the dictionary or not def match_words(dictionary, sentence, n, m):
# map to store all words in
# dictionary with their count
mp = dict ()
# adding all words in map
for i in range (n):
mp[dictionary[i]] = mp.get(dictionary[i], 0 ) + 1
# search in map for all
# words in the sentence
for i in range (m):
if (mp[sentence[i]]):
mp[sentence[i]] - = 1
else :
return False
# all words of sentence are present
return True
# Driver Code dictionary = [ "find" , "a" , "geeks" , "all" , "for" ,
"on" , "geeks" , "answers" , "inter" ]
n = len (dictionary)
sentence = [ "find" , "all" , "answers" , "on" ,
"geeks" , "for" , "geeks" ]
m = len (sentence)
# Calling function to check if words are # present in the dictionary or not if (match_words(dictionary, sentence, n, m)):
print ( "YES" )
else :
print ( "NO" )
# This code is contributed by mohit kumar |
// C# program to check if a sentence // can be formed from a given set of words. using System;
using System.Collections.Generic;
class GFG
{ // Function to check if the word // is in the dictionary or not static Boolean match_words(String []dictionary,
String []sentence,
int n, int m)
{ // map to store all words in
// dictionary with their count
Dictionary<String,
int > mp = new Dictionary<String,
int >();
// adding all words in map
for ( int i = 0; i < n; i++)
{
if (mp.ContainsKey(dictionary[i]))
{
mp[dictionary[i]] = mp[dictionary[i]] + 1;
}
else
{
mp.Add(dictionary[i], 1);
}
}
// search in map for all
// words in the sentence
for ( int i = 0; i < m; i++)
{
if (mp.ContainsKey(sentence[i]) && mp[sentence[i]] > 0)
mp[sentence[i]] = mp[sentence[i]] - 1;
else
return false ;
}
// all words of sentence are present
return true ;
} // Driver Code public static void Main(String[] args)
{ String []dictionary = { "find" , "a" , "geeks" ,
"all" , "for" , "on" ,
"geeks" , "answers" , "inter" };
int n = dictionary.Length;
String []sentence = { "find" , "all" , "answers" , "on" ,
"geeks" , "for" , "geeks" , "geeks" };
int m = sentence.Length;
// Calling function to check if words are
// present in the dictionary or not
if (match_words(dictionary, sentence, n, m))
Console.WriteLine( "YES" );
else
Console.WriteLine( "NO" );
} } // This code is contributed by Rajput-Ji |
<script> // Javascript program to check if a sentence // can be formed from a given set of words. // Function to check if the word // is in the dictionary or not function match_words(dictionary, sentence, n, m)
{ // map to store all words in
// dictionary with their count
let mp = new Map();
// Adding all words in map
for (let i = 0; i < n; i++)
{
if (mp.has(dictionary[i]))
{
mp.set(dictionary[i],
mp.get(dictionary[i]) + 1);
}
else
{
mp.set(dictionary[i], 1);
}
}
// Search in map for all
// words in the sentence
for (let i = 0; i < m; i++)
{
if (mp.has(sentence[i]))
mp.set(sentence[i],
mp.get(sentence[i]) - 1);
else
return false ;
}
// All words of sentence are present
return true ;
} // Driver code let dictionary = [ "find" , "a" , "geeks" ,
"all" , "for" , "on" ,
"geeks" , "answers" , "inter" ];
let n = dictionary.length; let sentence = [ "find" , "all" , "answers" , "on" ,
"geeks" , "for" , "geeks" ];
let m = sentence.length; // Calling function to check if words are // present in the dictionary or not if (match_words(dictionary, sentence, n, m))
document.write( "YES" );
else document.write( "NO" );
// This code is contributed by patel2127 </script> |
YES
Time Complexity: O(max(M,N))
Space Complexity: O(N) where N is no of words in a dictionary