Check if a string can be formed from another string using given constraints - GeeksforGeeks

03 Jun, 2021
Given two strings S1 and S2(all characters are in lower-case). The task is to check if S2 can be formed from S1 using given constraints: 1. Characters of S2 is there in S1 if there are two ‘a’ in S2, then S1 should have two ‘a’ also. 2. If any character of S2 is not present in S1, check if the previous two ASCII characters are there in S1. e.g., if ‘e’ is there in S2 and not in S1, then ‘c’ and ‘d’ can be used from S1 to make ‘e’. Note: All characters from S1 can be used only once. 
Examples: 
Input: S= abbat, W= cat Output: YES ‘c’ is formed from ‘a’ and ‘b’, ‘a’ and ‘t’ is present in S1. 
Input: S= abbt, W= cat Output: NO ‘c’ is formed from ‘a’ and ‘b’, but to form the next character ‘a’ in S2, there is no more unused ‘a’ left in S1. 
Approach: The above problem can be solved using hashing. The count of all the characters in S1 is stored in a hash-table. Traverse in the string, and check if the character in S2 is there in the hash-table, reduce the count of that particular character in the hash-table. If the character is not there in the hash-table, check if the previous two ASCII characters are there in the hash-table, then reduce the count of the previous two ASCII characters in the hash-table. If all the characters can be formed from S1 using the given constraints, the string S2 can be formed from S1, else it cannot be formed. 
Below is the implementation of the above approach:  
C++
Java
Python3
C#
Javascript
// CPP program to Check if a given// string can be formed from another// string using given constraints#include <bits/stdc++.h>using namespace std; // Function to check if S2 can be formed of S1bool check(string S1, string S2){    // length of strings    int n1 = S1.size();    int n2 = S2.size();     // hash-table to store count    unordered_map<int, int> mp;     // store count of each character    for (int i = 0; i < n1; i++) {        mp[S1[i]]++;    }     // traverse and check for every character    for (int i = 0; i < n2; i++) {         // if the character of s2 is present in s1        if (mp[S2[i]]) {            mp[S2[i]]--;        }         // if the character of s2 is not present in        // S1, then check if previous two ASCII characters        // are present in S1        else if (mp[S2[i] - 1] && mp[S2[i] - 2]) {             mp[S2[i] - 1]--;            mp[S2[i] - 2]--;        }        else {            return false;        }    }    return true;} // Driver Codeint main(){    string S1 = "abbat";    string S2 = "cat";     // Calling function to check    if (check(S1, S2))        cout << "YES";    else        cout << "NO";}
// JAVA program to Check if a given// String can be formed from another// String using given constraintsimport java.util.*; class GFG{ // Function to check if S2 can be formed of S1static boolean check(String S1, String S2){    // length of Strings    int n1 = S1.length();    int n2 = S2.length();     // hash-table to store count    HashMap<Integer,Integer> mp =        new HashMap<Integer,Integer>();     // store count of each character    for (int i = 0; i < n1; i++)    {        if(mp.containsKey((int)S1.charAt(i)))        {            mp.put((int)S1.charAt(i),            mp.get((int)S1.charAt(i)) + 1);        }        else        {            mp.put((int)S1.charAt(i), 1);        }    }     // traverse and check for every character    for (int i = 0; i < n2; i++)    {         // if the character of s2 is present in s1        if(mp.containsKey((int)S2.charAt(i)))        {            mp.put((int)S2.charAt(i),            mp.get((int)S2.charAt(i)) - 1);        }         // if the character of s2 is not present in        // S1, then check if previous two ASCII characters        // are present in S1        else if (mp.containsKey(S2.charAt(i)-1) &&                    mp.containsKey(S2.charAt(i)-2))        {            mp.put((S2.charAt(i) - 1),            mp.get(S2.charAt(i) - 1) - 1);            mp.put((S2.charAt(i) - 2),            mp.get(S2.charAt(i) - 2) - 1);        }        else        {            return false;        }    }     return true;} // Driver Codepublic static void main(String[] args){    String S1 = "abbat";    String S2 = "cat";     // Calling function to check    if (check(S1, S2))        System.out.print("YES");    else        System.out.print("NO");}} // This code is contributed by PrinciRaj1992
# Python3 program to Check if a given string# can be formed from another string using# given constraintsfrom collections import defaultdict # Function to check if S2 can# be formed of S1def check(S1, S2):     # length of strings    n1 = len(S1)    n2 = len(S2)     # hash-table to store count    mp = defaultdict(lambda:0)     # store count of each character    for i in range(0, n1):        mp[S1[i]] += 1     # traverse and check for every character    for i in range(0, n2):         # if the character of s2 is        # present in s1        if mp[S2[i]]:            mp[S2[i]] -= 1         # if the character of s2 is not present        # in S1, then check if previous two ASCII        # characters are present in S1        elif (mp[chr(ord(S2[i]) - 1)] and              mp[chr(ord(S2[i]) - 2)]):             mp[chr(ord(S2[i]) - 1)] -= 1            mp[chr(ord(S2[i]) - 2)] -= 1                 else:            return False     return True # Driver Codeif __name__ == "__main__":     S1 = "abbat"    S2 = "cat"     # Calling function to check    if check(S1, S2):        print("YES")    else:        print("NO") # This code is contributed by Rituraj Jain
// C# program to Check if a given// String can be formed from another// String using given constraintsusing System;using System.Collections.Generic; class GFG{ // Function to check if S2 can be formed of S1static bool check(String S1, String S2){    // length of Strings    int n1 = S1.Length;    int n2 = S2.Length;     // hash-table to store count    Dictionary<int,int> mp =        new Dictionary<int,int>();     // store count of each character    for (int i = 0; i < n1; i++)    {        if(mp.ContainsKey((int)S1[i]))        {            mp[(int)S1[i]] = mp[(int)S1[i]] + 1;        }        else        {            mp.Add((int)S1[i], 1);        }    }     // traverse and check for every character    for (int i = 0; i < n2; i++)    {         // if the character of s2 is present in s1        if(mp.ContainsKey((int)S2[i]))        {            mp[(int)S2[i]] = mp[(int)S2[i]] - 1;        }         // if the character of s2 is not present in        // S1, then check if previous two ASCII characters        // are present in S1        else if (mp.ContainsKey(S2[i] - 1) &&                    mp.ContainsKey(S2[i] - 2))        {            mp[S2[i] - 1] = mp[S2[i] - 1] - 1;            mp[S2[i] - 2] = mp[S2[i] - 2] - 1;        }        else        {            return false;        }    }     return true;} // Driver Codepublic static void Main(String[] args){    String S1 = "abbat";    String S2 = "cat";     // Calling function to check    if (check(S1, S2))        Console.Write("YES");    else        Console.Write("NO");}} // This code is contributed by PrinciRaj1992
<script> // JavaScript program to Check if a given// String can be formed from another// String using given constraints // Function to check if S2 can be formed of S1function check(S1, S2){         // Length of Strings    var n1 = S1.length;    var n2 = S2.length;         // hash-table to store count    var mp = {};         // Store count of each character    for(var i = 0; i < n1; i++)    {        if (mp.hasOwnProperty(S1[i]))        {            mp[S1[i]] = mp[S1[i]] + 1;        }        else        {            mp[S1[i]] = 1;        }    }         // Traverse and check for every character    for(var i = 0; i < n2; i++)    {                 // If the character of s2 is present in s1        if (mp.hasOwnProperty(S2[i]))        {            mp[S2[i]] = mp[S2[i]] - 1;        }             // If the character of s2 is not present        // in S1, then check if previous two ASCII        // characters are present in S1        else if (mp.hasOwnProperty(            String.fromCharCode(S2[i].charCodeAt(0) - 1)) &&            mp.hasOwnProperty(            String.fromCharCode(S2[i].charCodeAt(0) - 2)))        {            mp[String.fromCharCode(                S2[i].charCodeAt(0) - 1)] =            mp[String.fromCharCode(                S2[i].charCodeAt(0) - 1)] - 1;            mp[String.fromCharCode(                S2[i].charCodeAt(0) - 2)] =            mp[String.fromCharCode(                S2[i].charCodeAt(0) - 2)] - 1;        }        else        {            return false;        }    }    return true;} // Driver Codevar S1 = "abbat";var S2 = "cat"; // Calling function to checkif (check(S1, S2))    document.write("YES");else    document.write("NO");     // This code is contributed by rdtank </script>
YES
 
rituraj_jain
princiraj1992
rdtank
Constructive Algorithms
cpp-unordered_map
C++
Pattern Searching
Pattern Searching
CPP
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Operator Overloading in C++
Polymorphism in C++
Sorting a vector in C++
Friend class and function in C++
Pair in C++ Standard Template Library (STL)
KMP Algorithm for Pattern Searching
Rabin-Karp Algorithm for Pattern Searching
Naive algorithm for Pattern Searching
Check if a string is substring of another
Boyer Moore Algorithm for Pattern Searching