Find a string which matches all the patterns in the given array - GeeksforGeeks

15 Oct, 2020
Given an array of strings arr[] which contains patterns of characters and “*” denoting any set of characters including the empty string. The task is to find a string that matches all the patterns in the array.Note: If there is no such possible pattern, print -1. Examples: 
Input: arr[] = {“pq*du*q”, “pq*abc*q”, “p*d*q”} Output: pqduabcdq Explanation: Pattern “pqduabcdq” matches all the strings: String 1: First “*” can be replaced by a empty string. Second “*” can be replaced by “abcdq”. String 2: First “*” can be replaced by “du” Second “*” can be replaced by “d” String 3: First “*” can be replaced by “q” Second “*” can be replaced by “uabcd”Input: arr[] = {“a*c”, “*”} Output: ac 
Approach: The idea is to find the common prefix and suffix string in all the patterns and then the middle of every pattern can be replaced by the first or last “*” in every pattern. Below is the illustration of the approach:
Create three empty strings that match with the prefix, suffix, and middle portion of every pattern.
Iterate over every pattern in the array, For every pattern: Find the first and last “*” in the pattern.Iterate over the existing prefix and check that if it matches the current prefix of the pattern, If any character doesn’t match with the pattern, return -1.If there is some portion that is leftover in the prefix of the current pattern, then append it to the prefix of the common string.Similarly, match the suffix of the pattern.Finally, append all the middle characters of the string except the “*” in the middle initialized string for the common string.
Find the first and last “*” in the pattern.
Iterate over the existing prefix and check that if it matches the current prefix of the pattern, If any character doesn’t match with the pattern, return -1.
If there is some portion that is leftover in the prefix of the current pattern, then append it to the prefix of the common string.
Similarly, match the suffix of the pattern.
Finally, append all the middle characters of the string except the “*” in the middle initialized string for the common string.
Finally, concatenate the portions of the common string that is the prefix, middle, and the suffix portion of the string.
Below is the implementation of the above approach:
C++
Python3
// C++ implementation to find the// string which matches// all the patterns #include<bits/stdc++.h>using namespace std; // Function to find a common string// which matches all the patternstring find(vector<string> S,int N){    // For storing prefix till    // first most * without conflicts    string pref;         // For storing suffix till    // last most * without conflicts    string suff;         // For storing all middle    // characters between    // first and last *    string mid;             // Loop to iterate over every    // pattern of the array    for (int i = 0; i < N; i++) {                 // Index of the first "*"        int first = int(            S[i].find_first_of('*')            );                    // Index of Last "*"        int last = int(            S[i].find_last_of('*')            );                 // Iterate over the first "*"        for (int z = 0; z < int(pref.size()) &&                              z < first; z++) {            if (pref[z] != S[i][z]) {                return "*";            }        }                 // Prefix till first most *        // without conflicts        for (int z = int(pref.size());                       z < first; z++) {            pref += S[i][z];        }                 // Iterate till last        // most * from last        for (int z = 0; z < int(suff.size()) &&               int(S[i].size())-1-z > last; z++) {            if (suff[z] != S[i][int(S[i].size())-1-z]) {                return "*";            }        }                 // Make suffix till last        // most * without conflicts        for (int z = int(suff.size());         int(S[i].size())-1-z > last; z++) {            suff += S[i][int(S[i].size())-1-z];        }                 // Take all middle characters        // in between first and last most *        for (int z = first; z <= last; z++) {            if (S[i][z] != '*') mid += S[i][z];        }    }         reverse(suff.begin(), suff.end());    return pref + mid + suff;} // Driver Codeint main() {     int N = 3;    vector<string> s(N);         // Take all    // the strings    s[0]="pq*du*q";    s[1]="pq*abc*q";    s[2]="p*d*q";         // Method for finding    // common string    cout<<find(s,N);         return 0;}
# Python3 implementation# to find the string which# matches all the patterns # Function to find a common# string which matches all# the patterndef find(S, N):     # For storing prefix    # till first most *    # without conflicts    pref = ""     # For storing suffix    # till last most *    # without conflicts    suff = ""     # For storing all middle    # characters between    # first and last *    mid = ""     # Loop to iterate over every    # pattern of the array    for i in range(N):         # Index of the first "*"        first = int(S[i].index("*"))         # Index of Last "*"        last = int(S[i].rindex("*"))         # Iterate over the first "*"        for z in range(len(pref)):            if(z < first):                if(pref[z] != S[i][z]):                    return "*"         # Prefix till first most *        # without conflicts        for z in range(len(pref),first):            pref += S[i][z];         # Iterate till last        # most * from last        for z in range(len(suff)):            if(len(S[i]) - 1 - z > last):                if(suff[z] != S[i][len(S[i]) - 1 - z]):                    return "*"         # Make suffix till last        # most * without conflicts        for z in range(len(suff),                       len(S[i]) - 1 - last):            suff += S[i][len(S[i]) - 1 - z]         # Take all middle characters        # in between first and last most *        for z in range(first, last + 1):            if(S[i][z] != '*'):                mid += S[i][z]         suff=suff[:: -1]    return pref + mid + suff # Driver CodeN = 3s = ["" for i in range(N)] # Take all# the stringss[0] = "pq*du*q"s[1] = "pq*abc*q"s[2] = "p*d*q" # Method for finding# common stringprint(find(s, N)) # This code is contributed by avanitrachhadiya2155
pqduabcdq


 
avanitrachhadiya2155
permutation
Combinatorial
Pattern Searching
Strings
Strings
permutation
Combinatorial
Pattern Searching
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Ways to sum to N using Natural Numbers up to K with repetitions allowed
Generate all possible combinations of K numbers that sums to N
Combinations with repetitions
Largest substring with same Characters
Generate all possible combinations of at most X characters from a given array
KMP Algorithm for Pattern Searching
Rabin-Karp Algorithm for Pattern Searching
Check if a string is substring of another
Naive algorithm for Pattern Searching
Boyer Moore Algorithm for Pattern Searching