Open In App

Check if String T can be made Substring of S by replacing given characters

Improve
Improve
Like Article
Like
Save
Share
Report

Given two strings S and T and a 2D array replace[][], where replace[i] = {oldChar, newChar} represents that the character oldChar of T is replaced with newChar. The task is to find if it is possible to make string T a substring of S by replacing characters according to the replace array. 

Note: Each character in T cannot be replaced more than once.

Example:

Input: S = “hoog3e7bar”, T = “geek”, replace = {{‘e’, ‘3’}, {‘t’, ‘7’}, {‘k’, ‘8’}}
Output: true
Explanation: Replace the first ‘e’ in T with ‘3’ and ‘k’ in T with ‘7’.
Now T = “g3e7” is a substring of S, so we return true.

Input: S = “gooleetbar”, T = “g00l”, replace = {{‘o’, ‘0’}}
Output: false

Approach: The problem can be solved using Hashing based on the following idea:

Keep a datastructure for storing all the mapping of replace array. Enumerate all substrings of S with the same length as T, and compare each substring to S for equality.

Follow the steps below to implement the above approach:

  • Initialize a map say unmap, for mapping all the characters that oldChar can replace with newChar.
  • Iterate over the replace array and do the mapping.
  • Iterate over all the subarray of S of length equals to given string T.
    • Check if the character in S is not equal to the character in T.
      • If not equal then check if there exists any replacement of T[j] in unmap.
      • If a mapping exists then continue.
      • Otherwise, break from the current iteration and look for the other substring.
  • If we successfully find a valid substring, then return true.
  • Otherwise, return false.

Below is the implementation of the above approach.

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if the string
// can be made substring of S
bool match(string S, string T,
           vector<vector<char> >& replace)
{
    // Initialise a map say unmap, for
    // mapping all the characters that
    // oldChar can replace with newChar
    unordered_map<char, unordered_set<char> > unmap;
    int m = S.size(), n = T.size();
 
    // Iterate over the replace array
    // and map in unmap
    for (auto c : replace) {
        unmap].insert(c[1]);
    }
 
    // Iterate over all the subarray in S
    // of length equals to given string T.
    for (int i = 0; i < m - n + 1; i++) {
        bool flag = true;
        for (int j = 0; j < n; j++) {
 
            // Check if the character in S
            // is not equal to character
            // in T. If not equal then
            // check if there exist any
            // replacement of T[j] in unmap.
            if (S[i + j] != T[j]) {
 
                // If mapping exists, continue
                if (unmap[T[j]].find(S[i + j])
                    != unmap[T[j]].end()) {
                    continue;
                }
 
                // Otherwise, break from
                // current iteration and look
                // for the another substring.
                else {
                    flag = false;
                    break;
                }
            }
        }
 
        // If we successfully found valid
        // substring, then return true
        if (flag)
            return true;
    }
 
    // Otherwise, return false
    return false;
}
 
// Drivers code
int main()
{
    string S = "hoog3e7bar", T = "geek";
    vector<vector<char> > replace
        = { { 'e', '3' }, { 't', '7' }, { 'k', '7' } };
 
    // Function call
    bool result = match(S, T, replace);
 
    if (result)
        cout << "YES" << endl;
    else
        cout << "NO" << endl;
 
    return 0;
}


Java




// Java code to implement the approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
  // Function to check if the string
  // can be made substring of S
  static boolean match(String S, String T,
                       char[][] replace)
  {
     
    // Initialise a map for mapping all
    // the characters that oldChar can
    // replace with newChar
    Map<Character, Set<Character> > unmap
      = new HashMap<>();
    int m = S.length(), n = T.length();
 
    // Iterate over the replace array
    // and map in unmap
    for (char[] c : replace) {
      if (!unmap.containsKey(c[0])) {
        unmap.put(c[0], new HashSet<>());
      }
      unmap.get(c[0]).add(c[1]);
    }
 
    // Iterate over all the subarray in S
    // of length equals to given string T.
    for (int i = 0; i < m - n + 1; i++) {
      boolean flag = true;
      for (int j = 0; j < n; j++)
      {
         
        // Check if the character in S
        // is not equal to character
        // in T. If not equal then
        // check if there exist any
        // replacement of T[j] in unmap.
        if (S.charAt(i + j) != T.charAt(j))
        {
           
          // If mapping exists, continue
          if (unmap.containsKey(T.charAt(j))
              && unmap.get(T.charAt(j))
              .contains(S.charAt(i + j))) {
            continue;
          }
           
          // Otherwise, break from
          // current iteration and look
          // for the another substring.
          else {
            flag = false;
            break;
          }
        }
      }
 
      // If we successfully found valid
      // substring, then return true
      if (flag)
        return true;
    }
 
    // Otherwise, return false
    return false;
  }
 
  public static void main(String[] args)
  {
    String S = "hoog3e7bar", T = "geek";
    char[][] replace
      = { { 'e', '3' }, { 't', '7' }, { 'k', '7' } };
 
    // Function call
    boolean result = match(S, T, replace);
 
    if (result) {
      System.out.println("YES");
    }
    else {
      System.out.println("NO");
    }
  }
}
 
// This code is contributed by lokeshmvs21.


Python3




# Python code to implement the approach
 
# Function to check if the string
# can be made substring of S
 
def match(S,T,replace):
    # Initialise a map say unmap, for
    # mapping all the characters that
    # oldChar can replace with newChar
    unmap={}
    m=len(S)
    n=len(T)
     
    # Iterate over the replace array
    # and map in unmap
    for c in replace:
        unmap]=c[1]
         
    # Iterate over all the subarray in S
    # of length equals to given string T.
    for i in range(m-n+1):
        flag=True
        for j in range(n):
            # Check if the character in S
            # is not equal to character
            # in T. If not equal then
            # check if there exist any
            # replacement of T[j] in unmap.
            if(S[i+j]!=T[j]):
                # If mapping exists, continue
                if S[i+j] in unmap.values():
                    continue
                 
                # Otherwise, break from
                # current iteration and look
                # for the another substring.
                else:
                    flag=False
                    break
                 
        # If we successfully found valid
        # substring, then return true
        if(flag):
            return True
    # Otherwise, return false
    return False
     
# Driver code
S="hoog3e7bar"
T="geek"
replace=[['e', '3'],['t', '7'],['k', '7']]
 
# Function call
result=match(S,T,replace)
 
if(result):
    print("Yes")
else:
    print("No")
     
 
# This code is contributed by Pushpesh Raj.


Javascript




       // JavaScript code for the above approach
       // Function to check if the string
       // can be made substring of S
       function match(S, T, replace)
       {
        
           // Initialise a map for mapping all
           // the characters that oldChar can
           // replace with newChar
           let unmap = new Map();
           let m = S.length;
           let n = T.length;
 
           // Iterate over the replace array
           // and map in unmap
           for (let c of replace) {
               if (!unmap.has(c[0])) {
                   unmap.set(c[0], new Set());
               }
               unmap.get(c[0]).add(c[1]);
           }
 
           // Iterate over all the subarray in S
           // of length equals to given string T.
           for (let i = 0; i < m - n + 1; i++) {
               let flag = true;
               for (let j = 0; j < n; j++)
               {
                
                   // Check if the character in S
                   // is not equal to character
                   // in T. If not equal then
                   // check if there exist any
                   // replacement of T[j] in unmap.
                   if (S[i + j] != T[j]) {
                       // If mapping exists, continue
                       if (unmap.has(T[j]) && unmap.get(T[j]).has(S[i + j])) {
                           continue;
                       }
                       // Otherwise, break from
                       // current iteration and look
                       // for the another substring.
                       else {
                           flag = false;
                           break;
                       }
                   }
               }
 
               // If we successfully found valid
               // substring, then return true
               if (flag) return true;
           }
 
           // Otherwise, return false
 
           return false;
       }
 
       // Driver code
       let S = "hoog3e7bar";
       let T = "geek";
       let replace = [
           ['e', '3'],
           ['t', '7'],
           ['k', '7'],
       ];
 
       // Function call
       let result = match(S, T, replace);
 
       if (result) {
           console.log("YES");
       } else {
           console.log("NO");
       }
 
// This code is contributed by Potta Lokesh


C#




using System;
 
using System;
using System.Collections.Generic;
 
public class Program {
    // Function to check if the string
    // can be made substring of S
    static bool Match(string S, string T, char[][] replace)
    {
        // Initialise a map for mapping all
        // the characters that oldChar can
        // replace with newChar
        Dictionary<char, HashSet<char> > unmap
            = new Dictionary<char, HashSet<char> >();
        int m = S.Length, n = T.Length;
 
        // Iterate over the replace array
        // and map in unmap
        foreach(char[] c in replace)
        {
            if (!unmap.ContainsKey(c[0])) {
                unmap.Add(c[0], new HashSet<char>());
            }
            unmap].Add(c[1]);
        }
 
        // Iterate over all the subarray in S
        // of length equals to given string T.
        for (int i = 0; i < m - n + 1; i++) {
            bool flag = true;
            for (int j = 0; j < n; j++) {
                // Check if the character in S
                // is not equal to character
                // in T. If not equal then
                // check if there exist any
                // replacement of T[j] in unmap.
                if (S[i + j] != T[j]) {
                    // If mapping exists, continue
                    if (unmap.ContainsKey(T[j])
                        && unmap[T[j]].Contains(S[i + j])) {
                        continue;
                    }
                    // Otherwise, break from
                    // current iteration and look
                    // for the another substring.
                    else {
                        flag = false;
                        break;
                    }
                }
            }
 
            // If we successfully found valid
            // substring, then return true
            if (flag)
                return true;
        }
 
        // Otherwise, return false
        return false;
    }
 
    static public void Main(string[] args)
    {
        string S = "hoog3e7bar", T = "geek";
        char[][] replace = { new char[] { 'e', '3' },
                             new char[] { 't', '7' },
                             new char[] { 'k', '7' } };
 
        // Function call
        bool result = Match(S, T, replace);
 
        if (result) {
            Console.WriteLine("YES");
        }
        else {
            Console.WriteLine("NO");
        }
    }
}


Output

YES

Time Complexity: O(N * M) where N and M are the length of the strings T and S respectively.
Auxiliary Space: O(D) where D is the size of the array replace[][].

Related Articles:



Last Updated : 14 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads