Check if String T can be made Substring of S by replacing given characters
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.
- Check if the character in S is not equal to the character in T.
- 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" ); } } } |
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:
- Introduction to String – Data Structures and Algorithms Tutorials
- Introduction to Hashing – Data Structures and Algorithms Tutorials
Please Login to comment...