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



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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 <bits/stdc++.h>
using namespace std;
  
// Function to encode given string
string encodeString(string str)
{
    unordered_map<char, int> 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<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
    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<string> dict = { "abb", "abc", "xyz", "xyy" };
    string pattern = "foo";
  
    findMatchedWords(dict, pattern);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<Character, Integer> 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
}

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<char, int> map = new Dictionary<char, int>();
        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

chevron_right


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:

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 <bits/stdc++.h>
using namespace std;
  
bool check(string pattern, string word)
{
    if (pattern.length() != word.length())
        return false;
  
    char ch[128] = { 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<string> 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<string> dict = { "abb", "abc", "xyz", "xyy" };
    string pattern = "foo";
  
    findMatchedWords(dict, pattern);
  
    return 0;
}
  
// This code is contributed by Ankur Goel

chevron_right


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