Find all strings that match specific pattern in a dictionary

Given a dictionary of words, find all strings that matches the given pattern where every character in the pattern is uniquely mapped to a character in the dictionary.

Examples:

Input:
dict = ["abb", "abc", "xyz", "xyy"];
pattern = "foo"
Output: [xyy abb]
Explanation:
xyy and abb have same character at index 1 and 2 like the pattern

Input:
dict = ["abb", "abc", "xyz", "xyy"];
pat = "mno"
Output: [abc xyz]
Explanation:
abc and xyz have all distinct characters, similar to the pattern

Input:
dict = ["abb", "abc", "xyz", "xyy"];
pattern = "aba"
Output: []
Explanation:
Pattern has same character at index 0 and 2.
No word in dictionary follows the pattern.

Input:
dict = ["abab", "aba", "xyz", "xyx"];
pattern = "aba"
Output: [aba xyx]
Explanation:
aba and xyx have same character at index 0 and 2 like the pattern

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

The idea is to encode the pattern in such a way that any word from the dictionary that matches the pattern will have same hash as that of the pattern after encoding. We iterate through all words in dictionary one by one and print the words that have same hash as that of the pattern.

Below is the implementation of above idea –

C++

 // C++ program to print all the strings that match the // given pattern where every character in the pattern is // uniquely mapped to a character in the dictionary #include using namespace std;    // Function to encode given string string encodeString(string str) {     unordered_map map;     string res = "";     int i = 0;        // for each character in given string     for (char ch : str) {         // If the character is occurring for the first         // time, assign next unique number to that char         if (map.find(ch) == map.end())             map[ch] = i++;            // append the number associated with current         // character into the output string         res += to_string(map[ch]);     }        return res; }    // Function to print all the strings that match the // given pattern where every character in the pattern is // uniquely mapped to a character in the dictionary void findMatchedWords(unordered_set dict,                       string pattern) {     // len is length of the pattern     int len = pattern.length();        // encode the string     string hash = encodeString(pattern);        // for each word in the dictionary     for (string word : dict) {         // If size of pattern is same as size of current         // dictionary word and both pattern and the word         // has same hash, print the word         if (word.length() == len && encodeString(word) == hash)             cout << word << " ";     } }    // Driver code int main() {     unordered_set dict = { "abb", "abc", "xyz", "xyy" };     string pattern = "foo";        findMatchedWords(dict, pattern);        return 0; }

Java

 // Java program to print all the strings that match the // given pattern where every character in the pattern is // uniquely mapped to a character in the dictionary import java.io.*; import java.util.*;    class GFG {        // Function to encode given string     static String encodeString(String str)     {         HashMap map = new HashMap<>();         String res = "";         int i = 0;            // for each character in given string         char ch;         for (int j = 0; j < str.length(); j++) {             ch = str.charAt(j);                // If the character is occurring for the first             // time, assign next unique number to that char             if (!map.containsKey(ch))                 map.put(ch, i++);                // append the number associated with current             // character into the output string             res += map.get(ch);         }            return res;     }        // Function to print all the strings that match the     // given pattern where every character in the pattern is     // uniquely mapped to a character in the dictionary     static void findMatchedWords(String[] dict, String pattern)     {         // len is length of the pattern         int len = pattern.length();            // encode the string         String hash = encodeString(pattern);            // for each word in the dictionary array         for (String word : dict) {             // If size of pattern is same as size of current             // dictionary word and both pattern and the word             // has same hash, print the word             if (word.length() == len && encodeString(word).equals(hash))                 System.out.print(word + " ");         }     }        // Driver code     public static void main(String args[])     {         String[] dict = { "abb", "abc", "xyz", "xyy" };         String pattern = "foo";            findMatchedWords(dict, pattern);     }        // This code is contributed     // by rachana soma }

C#

 // C# program to print all the strings // that match the given pattern where // every character in the pattern is // uniquely mapped to a character in the dictionary using System; using System.Collections.Generic; public class GFG {        // Function to encode given string     static String encodeString(String str)     {         Dictionary map = new Dictionary();         String res = "";         int i = 0;            // for each character in given string         char ch;         for (int j = 0; j < str.Length; j++) {             ch = str[j];                // If the character is occurring for the first             // time, assign next unique number to that char             if (!map.ContainsKey(ch))                 map.Add(ch, i++);                // append the number associated with current             // character into the output string             res += map[ch];         }            return res;     }        // Function to print all the     // strings that match the     // given pattern where every     // character in the pattern is     // uniquely mapped to a character     // in the dictionary     static void findMatchedWords(String[] dict, String pattern)     {         // len is length of the pattern         int len = pattern.Length;            // encode the string         String hash = encodeString(pattern);            // for each word in the dictionary array         foreach(String word in dict)         {             // If size of pattern is same as             // size of current dictionary word             // and both pattern and the word             // has same hash, print the word             if (word.Length == len && encodeString(word).Equals(hash))                 Console.Write(word + " ");         }     }        // Driver code     public static void Main(String[] args)     {         String[] dict = { "abb", "abc", "xyz", "xyy" };         String pattern = "foo";            findMatchedWords(dict, pattern);     } }    // This code is contributed by 29AjayKumar

Output:

xyy abb

Another Approach:

The idea is to traverse both the pattern and word in parallel and for every first occurrence of any character in pattern we map it to the corresponding character present in word, and for any subsequent occurrence of the same character in pattern, there must me the same character in word which was earlier mapped.
For first occurrence of any character in pattern, we do ch[pattern[i]] = word[i].
and subsequent occurrence of any character must satisfy ch[pattern[i]] == word[i].

Below is the implementation of the above approach:

 // C++ program to print all the strings that match the // given pattern where every character in the pattern is // uniquely mapped to a character in the dictionary #include using namespace std;    bool check(string pattern, string word) {     if (pattern.length() != word.length())         return false;        char ch = { 0 };        int len = word.length();        for (int i = 0; i < len; i++) {         if (ch[pattern[i]] == 0)             ch[pattern[i]] = word[i];         else if (ch[pattern[i]] != word[i])             return false;     }        return true; }    // Function to print all the strings that match the // given pattern where every character in the pattern is // uniquely mapped to a character in the dictionary void findMatchedWords(unordered_set dict,                       string pattern) {     // len is length of the pattern     int len = pattern.length();        // for each word in the dictionary     for (string word : dict) {            if (check(pattern, word))             cout << word << " ";     } }    // Driver code int main() {     unordered_set dict = { "abb", "abc", "xyz", "xyy" };     string pattern = "foo";        findMatchedWords(dict, pattern);        return 0; }    // This code is contributed by Ankur Goel

Output:

xyy abb

This article is contributed by Aditya Goel. 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.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

My Personal Notes arrow_drop_up