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.
- 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++ 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 pattern string 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 Code int 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;
} |
import java.util.*;
public class Main {
// Function to find a common string
// which matches all the pattern
public static String find(ArrayList<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 = S.get(i).indexOf( '*' );
// Index of Last "*"
int last = S.get(i).lastIndexOf( '*' );
// Iterate over the first "*"
for ( int z = 0 ; z < pref.length() && z < first; z++) {
if (pref.charAt(z) != S.get(i).charAt(z)) {
return "*" ;
}
}
// Prefix till first most *
// without conflicts
for ( int z = pref.length(); z < first; z++) {
pref += S.get(i).charAt(z);
}
// Iterate till last
// most * from last
for ( int z = 0 ; z < suff.length() &&
S.get(i).length()- 1 -z > last; z++) {
if (suff.charAt(z) != S.get(i).charAt(S.get(i).length()- 1 -z)) {
return "*" ;
}
}
// Make suffix till last
// most * without conflicts
for ( int z = suff.length();
S.get(i).length()- 1 -z > last; z++) {
suff += S.get(i).charAt(S.get(i).length()- 1 -z);
}
// Take all middle characters
// in between first and last most *
for ( int z = first; z <= last; z++) {
if (S.get(i).charAt(z) != '*' ) mid += S.get(i).charAt(z);
}
}
suff = new StringBuilder(suff).reverse().toString();
return pref + mid + suff;
}
// Driver Code
public static void main(String[] args) {
int N = 3 ;
ArrayList<String> s = new ArrayList<>();
// Take all
// the strings
s.add( "pq*du*q" );
s.add( "pq*abc*q" );
s.add( "p*d*q" );
// Method for finding
// common string
System.out.println(find(s, N));
}
} // This code is contributed by divyansh2212 |
# Python3 implementation # to find the string which # matches all the patterns # Function to find a common # string which matches all # the pattern def 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 Code N = 3
s = ["" for i in range (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 print (find(s, N))
# This code is contributed by avanitrachhadiya2155 |
// C# program to find the // string which matches // all the patterns using System;
using System.Collections.Generic;
using System.Linq;
class Program
{ // Function to find a common string
// which matches all the pattern
static string Find(List< 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 = S[i].IndexOf( '*' );
// Index of Last "*"
int last = S[i].LastIndexOf( '*' );
// Iterate over the first "*"
for ( int z = 0; z < pref.Length && z < first; z++)
{
if (pref[z] != S[i][z])
{
return "*" ;
}
}
// Prefix till first most *
// without conflicts
for ( int z = pref.Length; z < first; z++)
{
pref += S[i][z];
}
// Iterate till last
// most * from last
for ( int z = 0; z < suff.Length && S[i].Length - 1 - z > last; z++)
{
if (suff[z] != S[i][S[i].Length - 1 - z])
{
return "*" ;
}
}
// Make suffix till last
// most * without conflicts
for ( int z = suff.Length; S[i].Length - 1 - z > last; z++)
{
suff += S[i][S[i].Length - 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];
}
}
}
return pref + mid + new string (suff.Reverse().ToArray());
}
// Driver code
static void Main( string [] args)
{
int N = 3;
// Take all
// the strings
List< string > S = new List< string >() { "pq*du*q" , "pq*abc*q" , "p*d*q" };
// Method for finding
// common string
Console.WriteLine(Find(S, N));
}
} // This code is contributed by Prince Kumar |
// Function to find a common string which matches all the pattern function find(S, N) {
// For storing prefix till first most * without conflicts
let pref = "" ;
// For storing suffix till last most * without conflicts
let suff = "" ;
// For storing all middle characters between first and last *
let mid = "" ;
// Loop to iterate over every pattern of the array
for (let i = 0; i < N; i++) {
// Index of the first "*"
const first = S[i].indexOf( "*" );
// Index of Last "*"
const last = S[i].lastIndexOf( "*" );
// Iterate over the first "*"
for (let z = 0; z < pref.length; z++) {
if (z < first) {
if (pref[z] !== S[i][z]) {
return "*" ;
}
}
}
// Prefix till first most * without conflicts
for (let z = pref.length; z < first; z++) {
pref += S[i][z];
}
// Iterate till last most * from last
for (let z = 0; z < suff.length; z++) {
if (S[i].length - 1 - z > last) {
if (suff[z] !== S[i][S[i].length - 1 - z]) {
return "*" ;
}
}
}
// Make suffix till last most * without conflicts
for (let z = suff.length; z < S[i].length - 1 - last; z++) {
suff += S[i][S[i].length - 1 - z];
}
// Take all middle characters in between first and last most *
for (let z = first; z <= last; z++) {
if (S[i][z] !== "*" ) {
mid += S[i][z];
}
}
}
// Reverse the suffix
suff = suff.split( "" ).reverse().join( "" );
// Return the common string
return pref + mid + suff;
} // Driver Code const N = 3; const s = [ "" , "" , "" ];
// Take all the strings s[0] = "pq*du*q" ;
s[1] = "pq*abc*q" ;
s[2] = "p*d*q" ;
// Method for finding common string console.log(find(s, N)); |
pqduabcdq