Check if String T can be made Substring of S by replacing given characters
Last Updated : 14 Jan, 2023
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[c[0]].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[0]]=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[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++) { 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"); } } }
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:
Similar Reads
Check if characters of a string can be made non-decreasing by replacing '?'s
Given a string S of length N consisting of lowercase English alphabets and '?', the task is to check if it is possible to make the string non-decreasing by replacing all the '?' characters with English alphabets. If found to be true, print "Yes". Otherwise, print "No". Examples: Input: S = "abb?xy?"
6 min read
Check if given string can be made Palindrome by removing only single type of character
Given a string S, the task is to whether a string can be made palindrome after removing the occurrences of the same character, any number of times Examples: Input: S = "abczdzacb" Output: Yes Explanation: Remove first and second occurrence of character 'a', string S becomes "bczdzcb", which is a pal
7 min read
Check if a two character string can be made using given words
Given a string of two characters and n distinct words of two characters. The task is to find if it is possible to arrange given words in such a way that the concatenated string has the given two character string as a substring. We can append a word multiple times. Examples: Input : str = "ya" words[
6 min read
Check if a string can be split into substrings starting with N followed by N characters
Given a string str, the task is to check if it can be split into substrings such that each substring starts with a numeric value followed by a number of characters represented by that numeric integer. Examples: Input: str = "4g12y6hunter" Output: Yes Explanation: Substrings "4g12y" and "6hunter" sat
5 min read
Check if string S can be converted to T by incrementing characters
Given strings S and T. The task is to check if S can be converted to T by performing at most K operations. For the ith operation, select any character in S which has not been selected before, and increment the chosen character i times (i.e., replacing it with the letter i times ahead in the alphabet
8 min read
Convert given Strings into T by replacing characters in between strings any number of times
Given an array, arr[] of N strings and a string T of size M, the task is to check if it is possible to make all the strings in the array arr[] same as the string T by removing any character from one string, say arr[i] and inserting it at any position to another string arr[j] any number of times. Exa
9 min read
Check if String S can be compressed to T by replacing some X characters with count X
Given two strings, S and T where S is a normal string and T is a compressed string, the task is to determine if the compressed string T can be achieved by compressing the string S. Note: A compression mechanism can arbitrarily delete X (X >= 0) characters and replace them with the deleted charact
7 min read
Searching For Characters and Substring in a String in Java
Efficient String manipulation is very important in Java programming especially when working with text-based data. In this article, we will explore essential methods like indexOf(), contains(), and startsWith() to search characters and substrings within strings in Java. Searching for a Character in a
5 min read
Find Strings formed by replacing prefixes of given String with given characters
Given a String ( S ) of length N and with that String, we need to print a triangle out of it. The triangle should start with the given string and keeps shrinking downwards by removing one character from the beginning of the string. The spaces on the left side of the triangle should be replaced with
9 min read
Check if String can be generated by concatenating character or String itself
Given a target string S consisting of lowercase alphabets, the task is to make this string by performing some operation on an empty string such that: The first operation is to append a lower case alphabet to string S and The second operation is to append a copy of S to itself. Note: The first operat
6 min read