Given a dictionary and a character array, print all valid words that are possible using characters from the array.
Examples:
Input : Dict - {"go","bat","me","eat","goal", "boy", "run"} arr[] = {'e','o','b', 'a','m','g', 'l'} Output : go, me, goal.
Asked In : Microsoft Interview
The idea is to use Trie data structure to store dictionary, then search words in Trie using characters of given array.
- Create an empty Trie and insert all words of given dictionary into the Trie.
- After that, we have pick only those characters in ‘Arr[]’ which are a child of the root of Trie.
- To quickly find whether a character is present in array or not, we create a hash of character arrays.
Below is the implementation of above idea
C++
// C++ program to print all valid words that // are possible using character of array #include<bits/stdc++.h> using namespace std;
// Converts key current character into index // use only 'a' through 'z' #define char_int(c) ((int)c - (int)'a') //converts current integer into character #define int_to_char(c) ((char)c + (char)'a') // Alphabet size #define SIZE (26) // trie Node struct TrieNode
{ TrieNode *Child[SIZE];
// isLeaf is true if the node represents
// end of a word
bool leaf;
}; // Returns new trie node (initialized to NULLs) TrieNode *getNode() { TrieNode * newNode = new TrieNode;
newNode->leaf = false ;
for ( int i =0 ; i< SIZE ; i++)
newNode->Child[i] = NULL;
return newNode;
} // If not present, inserts key into trie // If the key is prefix of trie node, just // marks leaf node void insert(TrieNode *root, char *Key)
{ int n = strlen (Key);
TrieNode * pChild = root;
for ( int i=0; i<n; i++)
{
int index = char_int(Key[i]);
if (pChild->Child[index] == NULL)
pChild->Child[index] = getNode();
pChild = pChild->Child[index];
}
// make last node as leaf node
pChild->leaf = true ;
} // A recursive function to print all possible valid // words present in array void searchWord(TrieNode *root, bool Hash[], string str)
{ // if we found word in trie / dictionary
if (root->leaf == true )
cout << str << endl ;
// traverse all child's of current root
for ( int K =0; K < SIZE; K++)
{
if (Hash[K] == true && root->Child[K] != NULL )
{
// add current character
char c = int_to_char(K);
// Recursively search reaming character of word
// in trie
searchWord(root->Child[K], Hash, str + c);
}
}
} // Prints all words present in dictionary. void PrintAllWords( char Arr[], TrieNode *root, int n)
{ // create a 'has' array that will store all present
// character in Arr[]
bool Hash[SIZE];
for ( int i = 0 ; i < n; i++)
Hash[char_int(Arr[i])] = true ;
// temporary node
TrieNode *pChild = root ;
// string to hold output words
string str = "" ;
// Traverse all matrix elements. There are only 26
// character possible in char array
for ( int i = 0 ; i < SIZE ; i++)
{
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (Hash[i] == true && pChild->Child[i] )
{
str = str+( char )int_to_char(i);
searchWord(pChild->Child[i], Hash, str);
str = "" ;
}
}
} //Driver program to test above function int main()
{ // Let the given dictionary be following
char Dict[][20] = { "go" , "bat" , "me" , "eat" ,
"goal" , "boy" , "run" } ;
// Root Node of Trie
TrieNode *root = getNode();
// insert all words of dictionary into trie
int n = sizeof (Dict)/ sizeof (Dict[0]);
for ( int i=0; i<n; i++)
insert(root, Dict[i]);
char arr[] = { 'e' , 'o' , 'b' , 'a' , 'm' , 'g' , 'l' } ;
int N = sizeof (arr)/ sizeof (arr[0]);
PrintAllWords(arr, root, N);
return 0;
} |
Java
// Java program to print all valid words that // are possible using character of array public class SearchDict_charArray {
// Alphabet size
static final int SIZE = 26 ;
// trie Node
static class TrieNode
{
TrieNode[] Child = new TrieNode[SIZE];
// isLeaf is true if the node represents
// end of a word
boolean leaf;
// Constructor
public TrieNode() {
leaf = false ;
for ( int i = 0 ; i< SIZE ; i++)
Child[i] = null ;
}
}
// If not present, inserts key into trie
// If the key is prefix of trie node, just
// marks leaf node
static void insert(TrieNode root, String Key)
{
int n = Key.length();
TrieNode pChild = root;
for ( int i= 0 ; i<n; i++)
{
int index = Key.charAt(i) - 'a' ;
if (pChild.Child[index] == null )
pChild.Child[index] = new TrieNode();
pChild = pChild.Child[index];
}
// make last node as leaf node
pChild.leaf = true ;
}
// A recursive function to print all possible valid
// words present in array
static void searchWord(TrieNode root, boolean Hash[],
String str)
{
// if we found word in trie / dictionary
if (root.leaf == true )
System.out.println(str);
// traverse all child's of current root
for ( int K = 0 ; K < SIZE; K++)
{
if (Hash[K] == true && root.Child[K] != null )
{
// add current character
char c = ( char ) (K + 'a' );
// Recursively search reaming character
// of word in trie
searchWord(root.Child[K], Hash, str + c);
}
}
}
// Prints all words present in dictionary.
static void PrintAllWords( char Arr[], TrieNode root,
int n)
{
// create a 'has' array that will store all
// present character in Arr[]
boolean [] Hash = new boolean [SIZE];
for ( int i = 0 ; i < n; i++)
Hash[Arr[i] - 'a' ] = true ;
// temporary node
TrieNode pChild = root ;
// string to hold output words
String str = "" ;
// Traverse all matrix elements. There are only
// 26 character possible in char array
for ( int i = 0 ; i < SIZE ; i++)
{
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (Hash[i] == true && pChild.Child[i] != null )
{
str = str+( char )(i + 'a' );
searchWord(pChild.Child[i], Hash, str);
str = "" ;
}
}
}
//Driver program to test above function
public static void main(String args[])
{
// Let the given dictionary be following
String Dict[] = { "go" , "bat" , "me" , "eat" ,
"goal" , "boy" , "run" } ;
// Root Node of Trie
TrieNode root = new TrieNode();
// insert all words of dictionary into trie
int n = Dict.length;
for ( int i= 0 ; i<n; i++)
insert(root, Dict[i]);
char arr[] = { 'e' , 'o' , 'b' , 'a' , 'm' , 'g' , 'l' } ;
int N = arr.length;
PrintAllWords(arr, root, N);
}
} // This code is contributed by Sumit Ghosh |
Python3
# Python program to print all valid words that # are possible using character of array # Alphabet size SIZE = 26
# trie Node class TrieNode:
def __init__( self ):
self .child = [ None ] * SIZE
# isLeaf is true if the node represents
# end of a word
self .leaf = False
# Converts key current character into index # use only 'a' through 'z' def char_int(c):
return ord (c) - ord ( 'a' )
# converts current integer into character def int_to_char(c):
return chr (c + ord ( 'a' ))
# Returns new trie node (initialized to NULLs) def get_node():
new_node = TrieNode()
return new_node
# If not present, inserts key into trie # If the key is prefix of trie node, just # marks leaf node def insert(root, key):
n = len (key)
p_child = root
for i in range (n):
index = char_int(key[i])
if not p_child.child[index]:
p_child.child[index] = get_node()
p_child = p_child.child[index]
# make last node as leaf node
p_child.leaf = True
# A recursive function to print all possible valid # words present in array def searchWord(root, hash , string):
# if we found word in trie / dictionary
if root.leaf:
print (string)
# traverse all child's of current root
for k in range (SIZE):
if hash [k] and root.child[k]:
# add current character
c = int_to_char(k)
# Recursively search reaming character of word
# in trie
searchWord(root.child[k], hash , string + c)
# Prints all words present in dictionary. def print_all_words(arr, root, n):
# create a 'has' array that will store all present
# character in Arr[]
hash = [ False ] * SIZE
for i in range (n):
hash [char_int(arr[i])] = True
# temporary node
p_child = root
# string to hold output words
string = ""
# Traverse all matrix elements. There are only 26
# character possible in char array
for i in range (SIZE):
# we start searching for word in dictionary
# if we found a character which is child
# of Trie root
if hash [i] and p_child.child[i]:
string = string + int_to_char(i)
searchWord(p_child.child[i], hash , string)
string = ""
# Driver program to test above function if __name__ = = '__main__' :
# Let the given dictionary be following
dict = [ "go" , "bat" , "me" , "eat" , "goal" , "boy" , "run" ]
# Root Node of Trie
root = get_node()
# insert all words of dictionary into trie
n = len ( dict )
for i in range (n):
insert(root, dict [i])
arr = [ 'e' , 'o' , 'b' , 'a' , 'm' , 'g' , 'l' ]
n = len (arr)
print_all_words(arr, root, n)
# This code is contributed by Aman Kumar. |
C#
// C# program to print all valid words that // are possible using character of array using System;
public class SearchDict_charArray
{ // Alphabet size
static readonly int SIZE = 26;
// trie Node
public class TrieNode
{
public TrieNode[] Child = new TrieNode[SIZE];
// isLeaf is true if the node represents
// end of a word
public Boolean leaf;
// Constructor
public TrieNode()
{
leaf = false ;
for ( int i =0 ; i< SIZE ; i++)
Child[i] = null ;
}
}
// If not present, inserts key into trie
// If the key is prefix of trie node, just
// marks leaf node
static void insert(TrieNode root, String Key)
{
int n = Key.Length;
TrieNode pChild = root;
for ( int i = 0; i < n; i++)
{
int index = Key[i] - 'a' ;
if (pChild.Child[index] == null )
pChild.Child[index] = new TrieNode();
pChild = pChild.Child[index];
}
// make last node as leaf node
pChild.leaf = true ;
}
// A recursive function to print all possible valid
// words present in array
static void searchWord(TrieNode root, Boolean []Hash,
String str)
{
// if we found word in trie / dictionary
if (root.leaf == true )
Console.WriteLine(str);
// traverse all child's of current root
for ( int K = 0; K < SIZE; K++)
{
if (Hash[K] == true && root.Child[K] != null )
{
// add current character
char c = ( char ) (K + 'a' );
// Recursively search reaming character
// of word in trie
searchWord(root.Child[K], Hash, str + c);
}
}
}
// Prints all words present in dictionary.
static void PrintAllWords( char []Arr, TrieNode root,
int n)
{
// create a 'has' array that will store all
// present character in Arr[]
Boolean[] Hash = new Boolean[SIZE];
for ( int i = 0 ; i < n; i++)
Hash[Arr[i] - 'a' ] = true ;
// temporary node
TrieNode pChild = root ;
// string to hold output words
String str = "" ;
// Traverse all matrix elements. There are only
// 26 character possible in char array
for ( int i = 0 ; i < SIZE ; i++)
{
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (Hash[i] == true && pChild.Child[i] != null )
{
str = str+( char )(i + 'a' );
searchWord(pChild.Child[i], Hash, str);
str = "" ;
}
}
}
// Driver code
public static void Main(String []args)
{
// Let the given dictionary be following
String []Dict = { "go" , "bat" , "me" , "eat" ,
"goal" , "boy" , "run" } ;
// Root Node of Trie
TrieNode root = new TrieNode();
// insert all words of dictionary into trie
int n = Dict.Length;
for ( int i = 0; i < n; i++)
insert(root, Dict[i]);
char []arr = { 'e' , 'o' , 'b' , 'a' , 'm' , 'g' , 'l' } ;
int N = arr.Length;
PrintAllWords(arr, root, N);
}
} /* This code is contributed by PrinciRaj1992 */ |
Javascript
<script> // JavaScript program to print all valid words that
// are possible using character of array
// Converts key current character into index
// use only 'a' through 'z'
function char_int(c) {
return c.charCodeAt(0) - "a" .charCodeAt(0);
}
//converts current integer into character
function int_to_char(c) {
return String.fromCharCode(c + "a" .charCodeAt(0));
}
// Alphabet size
const SIZE = 26;
// Trie Node
class TrieNode {
constructor() {
this .Child = new Array(SIZE);
// isLeaf is true if the node represents
// end of a word
this .leaf = false ;
}
}
// Returns new trie node (initialized to NULLs)
function getNode() {
const newNode = new TrieNode();
newNode.leaf = false ;
for (let i = 0; i < SIZE; i++) {
newNode.Child[i] = null ;
}
return newNode;
}
// If not present, inserts key into trie
// If the key is prefix of trie node, just
// marks leaf node
function insert(root, Key) {
const n = Key.length;
let pChild = root;
for (let i = 0; i < n; i++) {
const index = char_int(Key[i]);
if (pChild.Child[index] == null ) {
pChild.Child[index] = getNode();
}
pChild = pChild.Child[index];
}
// make last node as leaf node
pChild.leaf = true ;
}
// A recursive function to print all possible valid
// words present in array
function searchWord(root, Hash, str) {
// if we found word in trie / dictionary
if (root.leaf == true ) {
document.write(str+ "<br>" );
}
// traverse all child's of current root
for (let K = 0; K < SIZE; K++) {
if (Hash[K] == true && root.Child[K] != null ) {
// add current character
const c = int_to_char(K);
// Recursively search remaining character of word
// in trie
searchWord(root.Child[K], Hash, str + c);
}
}
}
// Prints all words present in dictionary.
function PrintAllWords(Arr, root, n) {
// create a 'has' array that will store all present
// character in Arr[]
const Hash = new Array(SIZE).fill( false );
for (let i = 0; i < n; i++) {
Hash[char_int(Arr[i])] = true ;
}
// temporary node
let pChild = root;
// string to hold output words
let str = "" ;
// Traverse all matrix elements. There are only 26
// character possible in char array
for (let i = 0; i < SIZE; i++) {
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (Hash[i] == true && pChild.Child[i]) {
str += int_to_char(i);
searchWord(pChild.Child[i], Hash, str);
str = "" ;
}
}
}
//Driver program to test above function
// Let the given dictionary be following
const Dict = [ "go" , "bat" , "me" , "eat" , "goal" , "boy" , "run" ];
// Root Node of Trie
const root = getNode();
// insert all words of dictionary into trie
const n = Dict.length;
for (let i = 0; i < n; i++) {
insert(root, Dict[i]);
}
const arr = [ "e" , "o" , "b" , "a" , "m" , "g" , "l" ];
const N = arr.length;
PrintAllWords(arr, root, N);
// This code is contributed by Utkarsh Kumar
</script> |
Output
bat boy eat go goal me run
Time Complexity: O(SIZE^L * N) where L is the length of the longest word in the dictionary and N is the length of the input array.
Auxiliary Space: O(SIZE^L)