Open In App

Check if a given pattern exists in a given string or not including wild cards * and .

Improve
Improve
Like Article
Like
Save
Share
Report

Given two strings text and pattern of length M and N respectively, The task is to check if the pattern matches the text or not. If found to be true, then print “Yes”. Otherwise, print “No”.

Note: pattern can include the characters ‘*’ and ‘•’

  • ‘*’ matches zero or more occurrences of character right before the current character
  • ‘•’ matches any signal character.

Examples:

Input: pattern = “ge*ksforgeeks”, text = “geeksforgeeks” 
Output: Yes 
Explanation: 
Replacing ‘*’ with ‘e’, modifies pattern equal to “geeksforgeeks”. 
Therefore, the required output is Yes.

Input: pattern = “ab*d”, text = “abcds”
Output: No 
Explanation: The given pattern cannot be matched with the text.

Naive Approach: Below is the idea to solve the problem:

The simplest approach to solve this problem is to iterate over the characters of the both the strings using recursion. If current character is ‘.’, replace current character to any character and recur for the remaining pattern and text string. Otherwise, if the current character is ‘*’, recur for the remaining text and check if it matches the rest of the pattern or not. If found to be true, then print “Yes”. Otherwise, print “No”

Time Complexity: O((M + N) * 2(M + N / 2?)
Auxiliary Space: O((M + N) * 2(M + N / 2?))

Check if a given pattern exists in a given string or not using Dynamic Programming

Below is the idea to solve the problem:

Construct a 2D array dp[M+1][N+1] with DP state dp[i][j] denoting if the first i characters of string text match with the first j characters of pattern then assign dp[i][j] as 1 else 0 according to the match of text[i] and pattern[j] and true value of dp[i-1][j-1]

  • Initialize a 2D array, dp[M + 1][N + 1], where dp[i][j] check if the substring {text[0], …, text[i]} matches with the substring {pattern[0], … pattern[j]} or not.
  • Iterate over the characters of the both the strings and fill the dp[][] array based on the following recurrence relation: 
    • If text[i] and pattern[j] are the same then characters match so fill dp[i + 1][j + 1] = dp[i][j].
    • If pattern[j] is ‘.’ then characters match so fill dp[i + 1][j + 1] = dp[i][j].
    • If pattern[j] is ‘*’ then check the following conditions: 
      • If text[i] is not equal to pattern[j – 1] and pattern[j – 1] is not equal to ‘.’, then characters don’t match so fill dp[i + 1][j + 1] = dp[i + 1][j – 1].
      • Otherwise, fill dp[i + 1][j + 1] = (dp[i + 1][j] || dp[i][j + 1] || dp[i + 1][j – 1]).
  • Finally, print the value of dp[M][N].

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if the pattern
// consisting of '*', '.' and lowercase
// characters matches the text or not
int isMatch(string text, string pattern)
{
 
    // Base Case
    if (text == "" or pattern == "")
        return false;
 
    // Stores length of text
    int N = text.size();
 
    // Stores length of pattern
    int M = pattern.size();
 
    // dp[i][j]: Check if { text[0], .. text[i] }
    // matches {pattern[0], ... pattern[j]} or not
    vector<vector<bool> > dp(N + 1,
                             vector<bool>(M + 1, false));
 
    // Base Case
    dp[0][0] = true;
 
    // Iterate over the characters
    // of the string pattern
    for (int i = 0; i < M; i++) {
        if (pattern[i] == '*' && dp[0][i - 1]) {
 
            // Update dp[0][i + 1]
            dp[0][i + 1] = true;
        }
    }
 
    // Iterate over the characters
    // of both the strings
    for (int i = 0; i < N; i++) {
 
        for (int j = 0; j < M; j++) {
 
            // If current character
            // in the pattern is '.'
            if (pattern[j] == '.') {
 
                // Update dp[i + 1][j + 1]
                dp[i + 1][j + 1] = dp[i][j];
            }
 
            // If current character in
            // both the strings are equal
            if (pattern[j] == text[i]) {
 
                // Update dp[i + 1][j + 1]
                dp[i + 1][j + 1] = dp[i][j];
            }
 
            // If current character
            // in the pattern is '*'
            if (pattern[j] == '*') {
 
                if (pattern[j - 1] != text[i]
                    && pattern[j - 1] != '.') {
 
                    // Update dp[i + 1][j + 1]
                    dp[i + 1][j + 1] = dp[i + 1][j - 1];
                }
 
                else {
 
                    // Update dp[i+1][j+1]
                    dp[i + 1][j + 1]
                        = (dp[i + 1][j] or dp[i][j + 1]
                           or dp[i + 1][j - 1]);
                }
            }
        }
    }
 
    // Return dp[M][N]
    return dp[N][M];
}
 
// Driver Code
int main()
{
    string text = "geeksforgeeks";
    string pattern = "ge*ksforgeeks";
 
    if (isMatch(text, pattern))
        cout << "Yes";
    else
        cout << "No";
}
 
// This code is contributed by mohiy kumar 29.


Java




// Java program for the above approach
 
import java.io.*;
 
class GFG {
 
    // Function to check if the pattern
    // consisting of '*', '.' and lowercase
    // characters matches the text or not
    static boolean isMatch(String text, String pattern)
    {
        // Base Case
        if (text == null || pattern == null) {
            return false;
        }
 
        // Stores length of text
        int N = text.length();
 
        // Stores length of pattern
        int M = pattern.length();
 
        // dp[i][j]: Check if { text[0], .. text[i] }
        // matches {pattern[0], ... pattern[j]} or not
        boolean[][] dp = new boolean[N + 1][M + 1];
 
        // Base Case
        dp[0][0] = true;
 
        // Iterate over the characters
        // of the string pattern
        for (int i = 0; i < M; i++) {
            if (pattern.charAt(i) == '*' && dp[0][i - 1]) {
 
                // Update dp[0][i + 1]
                dp[0][i + 1] = true;
            }
        }
 
        // Iterate over the characters
        // of both the strings
        for (int i = 0; i < N; i++) {
 
            for (int j = 0; j < M; j++) {
 
                // If current character
                // in the pattern is '.'
                if (pattern.charAt(j) == '.') {
 
                    // Update dp[i + 1][j + 1]
                    dp[i + 1][j + 1] = dp[i][j];
                }
 
                // If current character in
                // both the strings are equal
                if (pattern.charAt(j) == text.charAt(i)) {
 
                    // Update dp[i + 1][j + 1]
                    dp[i + 1][j + 1] = dp[i][j];
                }
 
                // If current character
                // in the pattern is '*'
                if (pattern.charAt(j) == '*') {
 
                    if (pattern.charAt(j - 1)
                            != text.charAt(i)
                        && pattern.charAt(j - 1) != '.') {
 
                        // Update dp[i + 1][j + 1]
                        dp[i + 1][j + 1] = dp[i + 1][j - 1];
                    }
 
                    else {
 
                        // Update dp[i+1][j+1]
                        dp[i + 1][j + 1]
                            = (dp[i + 1][j] || dp[i][j + 1]
                               || dp[i + 1][j - 1]);
                    }
                }
            }
        }
 
        // Return dp[M][N]
        return dp[N][M];
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String text = "geeksforgeeks";
        String pattern = "ge*ksforgeeks";
 
        if (isMatch(text, pattern)) {
 
            System.out.println("Yes");
        }
        else {
 
            System.out.println("No");
        }
    }
}


Python3




# Python3 program for the above approach
#import numpy as np
 
# Function to check if the pattern
# consisting of '*', '.' and lowercase
# characters matches the text or not
 
 
def isMatch(text, pattern):
 
    # Base Case
    if (text == "" or pattern == ""):
        return False
 
    # Stores length of text
    N = len(text)
 
    # Stores length of pattern
    M = len(pattern)
 
    # dp[i][j]: Check if { text[0], .. text[i] }
    # matches {pattern[0], ... pattern[j]} or not
    #dp = np.zeros((N + 1, M + 1))
 
    rows, cols = (N + 1, M + 1)
    dp = [[0]*cols]*rows
 
    # Base Case
    dp[0][0] = True
 
    # Iterate over the characters
    # of the string pattern
    for i in range(M):
        if (pattern[i] == '*' and dp[0][i - 1]):
 
            # Update dp[0][i + 1]
            dp[0][i + 1] = True
 
    # Iterate over the characters
    # of both the strings
    for i in range(N):
        for j in range(M):
 
            # If current character
            # in the pattern is '.'
            if (pattern[j] == '.'):
 
                # Update dp[i + 1][j + 1]
                dp[i + 1][j + 1] = dp[i][j]
 
            # If current character in
            # both the strings are equal
            if (pattern[j] == text[i]):
 
                # Update dp[i + 1][j + 1]
                dp[i + 1][j + 1] = dp[i][j]
 
            # If current character
            # in the pattern is '*'
            if (pattern[j] == '*'):
                if (pattern[j - 1] != text[i] and
                        pattern[j - 1] != '.'):
 
                    # Update dp[i + 1][j + 1]
                    dp[i + 1][j + 1] = dp[i + 1][j - 1]
 
                else:
 
                    # Update dp[i+1][j+1]
                    dp[i + 1][j + 1] = (dp[i + 1][j] or
                                        dp[i][j + 1] or
                                        dp[i + 1][j - 1])
 
    # Return dp[M][N]
    return dp[N][M]
 
 
# Driver Code
if __name__ == "__main__":
 
    text = "geeksforgeeks"
    pattern = "ge*ksforgeeks"
 
    if (isMatch(text, pattern)):
        print("Yes")
    else:
        print("No")
 
# This code is contributed by AnkThon


Javascript




<script>
 
    // JavaScript program for the above approach
     
    // Function to check if the pattern
    // consisting of '*', '.' and lowercase
    // characters matches the text or not
    function isMatch(text, pattern)
    {
        // Base Case
        if (text == null || pattern == null) {
            return false;
        }
  
        // Stores length of text
        let N = text.length;
  
        // Stores length of pattern
        let M = pattern.length;
  
        // dp[i][j]: Check if { text[0], .. text[i] }
        // matches {pattern[0], ... pattern[j]} or not
        let dp = new Array(N + 1);
        for (let i = 0; i <= N; i++)
        {
            dp[i] = new Array(M + 1);
            for (let j = 0; j <= M; j++)
            {
                dp[i][j] = false;
            }
        }
         
  
        // Base Case
        dp[0][0] = true;
  
        // Iterate over the characters
        // of the string pattern
        for (let i = 0; i < M; i++) {
            if (pattern[i] == '*'
                && dp[0][i - 1]) {
  
                // Update dp[0][i + 1]
                dp[0][i + 1] = true;
            }
        }
  
        // Iterate over the characters
        // of both the strings
        for (let i = 0; i < N; i++) {
  
            for (let j = 0; j < M; j++) {
  
                // If current character
                // in the pattern is '.'
                if (pattern[j] == '.') {
  
                    // Update dp[i + 1][j + 1]
                    dp[i + 1][j + 1] = dp[i][j];
                }
  
                // If current character in
                // both the strings are equal
                if (pattern[j] == text[i]) {
  
                    // Update dp[i + 1][j + 1]
                    dp[i + 1][j + 1] = dp[i][j];
                }
  
                // If current character
                // in the pattern is '*'
                if (pattern[j] == '*') {
  
                    if (pattern[j - 1] != text[i]
                        && pattern[j - 1] != '.') {
  
                        // Update dp[i + 1][j + 1]
                        dp[i + 1][j + 1] = dp[i + 1][j - 1];
                    }
  
                    else {
  
                        // Update dp[i+1][j+1]
                        dp[i + 1][j + 1] = (dp[i + 1][j]
                                            || dp[i][j + 1]
                                            || dp[i + 1][j - 1]);
                    }
                }
            }
        }
  
        // Return dp[M][N]
        return dp[N][M];
    }
     
    let text = "geeksforgeeks";
    let pattern = "ge*ksforgeeks";
 
    if (isMatch(text, pattern)) {
      document.write("Yes");
    }
    else {
      document.write("No");
    }
 
</script>


C#




// C# program for the above approach
using System;
 
class GFG {
 
    // Function to check if the pattern
    // consisting of '*', '.' and lowercase
    // characters matches the text or not
    static bool isMatch(string text, string pattern)
    {
 
        // Base Case
        if (text == null || pattern == null) {
            return false;
        }
 
        // Stores length of text
        int N = text.Length;
 
        // Stores length of pattern
        int M = pattern.Length;
 
        // dp[i][j]: Check if { text[0], .. text[i] }
        // matches {pattern[0], ... pattern[j]} or not
        bool[, ] dp = new bool[N + 1, M + 1];
 
        // Base Case
        dp[0, 0] = true;
 
        // Iterate over the characters
        // of the string pattern
        for (int i = 0; i < M; i++) {
            if (pattern[i] == '*' && dp[0, i - 1]) {
 
                // Update dp[0][i + 1]
                dp[0, i + 1] = true;
            }
        }
 
        // Iterate over the characters
        // of both the strings
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
 
                // If current character
                // in the pattern is '.'
                if (pattern[j] == '.') {
 
                    // Update dp[i + 1][j + 1]
                    dp[i + 1, j + 1] = dp[i, j];
                }
 
                // If current character in
                // both the strings are equal
                if (pattern[j] == text[i]) {
 
                    // Update dp[i + 1][j + 1]
                    dp[i + 1, j + 1] = dp[i, j];
                }
 
                // If current character
                // in the pattern is '*'
                if (pattern[j] == '*') {
                    if (pattern[j - 1] != text[i]
                        && pattern[j - 1] != '.') {
 
                        // Update dp[i + 1][j + 1]
                        dp[i + 1, j + 1] = dp[i + 1, j - 1];
                    }
 
                    else {
 
                        // Update dp[i+1][j+1]
                        dp[i + 1, j + 1]
                            = (dp[i + 1, j] || dp[i, j + 1]
                               || dp[i + 1, j - 1]);
                    }
                }
            }
        }
 
        // Return dp[M][N]
        return dp[N, M];
    }
 
    // Driver Code
    public static void Main()
    {
        string text = "geeksforgeeks";
        string pattern = "ge*ksforgeeks";
 
        if (isMatch(text, pattern)) {
            Console.WriteLine("Yes");
        }
        else {
            Console.WriteLine("No");
        }
    }
}
 
// This code is contributed by ukasp


Output

Yes

Time Complexity: O(M * N)
Auxiliary Space: O(M * N)

Efficient Approach : using array instead of 2d matrix to optimize space complexity 

In previous code we can se that dp[i][j] is dependent upon dp[i+1][j-1] or dp[i][j-1] so we can assume that dp[i+1] is current row and dp[i] is previous row.

Implementations Steps :

  • Initialize a 1D boolean vector ‘dp’ of size M+1, where M is the length of the pattern.
  • Base case: dp[0] is true, as an empty pattern matches an empty text.
  • Iterate over the characters of the pattern. If the current character is ‘*’, update dp[i+1] to true if dp[i-1] is true.
  • Iterate over the characters of the text. Keep a variable ‘prev’ to store the previous value of dp[j]. For each character in the pattern, update dp[j+1] based on the current and previous values of dp[j], dp[j-1], and prev, depending on the character in the pattern.
  • Return dp[M] as the final answer. If dp[M] is true, the pattern matches the text; otherwise, it does not.

Implementation :

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if the pattern
// consisting of '*', '.' and lowercase
// characters matches the text or not
int isMatch(string text, string pattern)
{
 
    // Base Case
    if (text == "" or pattern == "")
        return false;
 
    // Stores length of text
    int N = text.size();
 
    // Stores length of pattern
    int M = pattern.size();
 
    // dp[j]: Check if { text[0], .. text[i] }
    // matches {pattern[0], ... pattern[j]} or not
    vector<bool> dp(M + 1, false);
 
    // Base Case
    dp[0] = true;
 
    // Iterate over the characters
    // of the string pattern
    for (int i = 0; i < M; i++) {
        if (pattern[i] == '*' && dp[i - 1]) {
 
            // Update dp[i + 1]
            dp[i + 1] = true;
        }
    }
 
    // Iterate over the characters
    // of both the strings
    for (int i = 0; i < N; i++) {
        bool prev = dp[0];
        dp[0] = false;
 
        for (int j = 0; j < M; j++) {
 
            bool temp = dp[j+1];
 
            // If current character
            // in the pattern is '.'
            if (pattern[j] == '.') {
 
                // Update dp[j + 1]
                dp[j + 1] = prev;
            }
 
            // If current character in
            // both the strings are equal
            else if (pattern[j] == text[i]) {
 
                // Update dp[j + 1]
                dp[j + 1] = prev;
            }
 
            // If current character
            // in the pattern is '*'
            else if (pattern[j] == '*') {
 
                if (pattern[j - 1] != text[i]
                    && pattern[j - 1] != '.') {
 
                    // Update dp[j + 1]
                    dp[j + 1] = dp[j - 1];
                }
 
                else {
 
                    // Update dp[j + 1]
                    dp[j + 1] = (dp[j + 1] or dp[j] or prev);
                }
            }
            else {
 
                // Update dp[j + 1]
                dp[j + 1] = false;
            }
 
            prev = temp;
        }
    }
 
    // Return dp[M]
    return dp[M];
}
 
// Driver Code
int main()
{
    string text = "geeksforgeeks";
    string pattern = "ge*ksforgeeks";
 
    if (isMatch(text, pattern))
        cout << "Yes";
    else
        cout << "No";
}
 
// this code is contributed by bhardwajji


Java




// Java program for the above approach
import java.util.*;
 
public class Main {
    // Function to check if the pattern
    // consisting of '*', '.' and lowercase
    // characters matches the text or not
    static int isMatch(String text, String pattern)
    { // Base Case
        if (text.equals("") || pattern.equals(""))
            return 0;
 
        // Stores length of text
        int N = text.length();
 
        // Stores length of pattern
        int M = pattern.length();
 
        // dp[j]: Check if { text[0], .. text[i] }
        // matches {pattern[0], ... pattern[j]} or not
        boolean[] dp = new boolean[M + 1];
 
        // Base Case
        dp[0] = true;
 
        // Iterate over the characters
        // of the string pattern
        for (int i = 0; i < M; i++) {
            if (pattern.charAt(i) == '*' && dp[i - 1]) {
 
                // Update dp[i + 1]
                dp[i + 1] = true;
            }
        }
 
        // Iterate over the characters
        // of both the strings
        for (int i = 0; i < N; i++) {
            boolean prev = dp[0];
            dp[0] = false;
 
            for (int j = 0; j < M; j++) {
 
                boolean temp = dp[j + 1];
 
                // If current character
                // in the pattern is '.'
                if (pattern.charAt(j) == '.') {
 
                    // Update dp[j + 1]
                    dp[j + 1] = prev;
                }
 
                // If current character in
                // both the strings are equal
                else if (pattern.charAt(j)
                         == text.charAt(i)) {
 
                    // Update dp[j + 1]
                    dp[j + 1] = prev;
                }
 
                // If current character
                // in the pattern is '*'
                else if (pattern.charAt(j) == '*') {
 
                    if (j > 0
                        && pattern.charAt(j - 1)
                               != text.charAt(i)
                        && pattern.charAt(j - 1) != '.') {
 
                        // Update dp[j + 1]
                        dp[j + 1] = dp[j - 1];
                    }
 
                    else {
 
                        // Update dp[j + 1]
                        dp[j + 1]
                            = (dp[j + 1] || dp[j] || prev);
                    }
                }
                else {
 
                    // Update dp[j + 1]
                    dp[j + 1] = false;
                }
 
                prev = temp;
            }
        }
 
        // Return dp[M]
        return dp[M] ? 1 : 0;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String text = "geeksforgeeks";
        String pattern = "ge*ksforgeeks";
 
        if (isMatch(text, pattern) == 1)
            System.out.println("Yes");
        else
            System.out.println("No");
    }
}


Python3




# Python program for the above approach
 
# Function to check if the pattern
# consisting of '*', '.' and lowercase
# characters matches the text or not
def isMatch(text, pattern):
    # Base Case
    if text == "" or pattern == "":
        return False
 
    # Stores length of text
    N = len(text)
 
    # Stores length of pattern
    M = len(pattern)
 
    # dp[j]: Check if { text[0], .. text[i] }
    # matches {pattern[0], ... pattern[j]} or not
    dp = [False] * (M + 1)
 
    # Base Case
    dp[0] = True
 
    # Iterate over the characters
    # of the string pattern
    for i in range(M):
        if pattern[i] == '*' and dp[i - 1]:
            # Update dp[i + 1]
            dp[i + 1] = True
 
    # Iterate over the characters
    # of both the strings
    for i in range(N):
        prev = dp[0]
        dp[0] = False
 
        for j in range(M):
            temp = dp[j + 1]
 
            # If current character
            # in the pattern is '.'
            if pattern[j] == '.':
                # Update dp[j + 1]
                dp[j + 1] = prev
 
            # If current character in
            # both the strings are equal
            elif pattern[j] == text[i]:
                # Update dp[j + 1]
                dp[j + 1] = prev
 
            # If current character
            # in the pattern is '*'
            elif pattern[j] == '*':
                if pattern[j - 1] != text[i] and pattern[j - 1] != '.':
                    # Update dp[j + 1]
                    dp[j + 1] = dp[j - 1]
                else:
                    # Update dp[j + 1]
                    dp[j + 1] = (dp[j + 1] or dp[j] or prev)
            else:
                # Update dp[j + 1]
                dp[j + 1] = False
 
            prev = temp
 
    # Return dp[M]
    return dp[M]
 
# Driver Code
if __name__ == '__main__':
    text = "geeksforgeeks"
    pattern = "ge*ksforgeeks"
 
    if isMatch(text, pattern):
        print("Yes")
    else:
        print("No")


Javascript




// Function to check if the pattern
// consisting of '*', '.' and lowercase
// characters matches the text or not
function isMatch(text, pattern) {
 
    // Base Case
    if (text === "" || pattern === "") {
        return false;
    }
 
    // Stores length of text
    let N = text.length;
 
    // Stores length of pattern
    let M = pattern.length;
 
    // dp[j]: Check if { text[0], .. text[i] }
    // matches {pattern[0], ... pattern[j]} or not
    let dp = new Array(M + 1).fill(false);
 
    // Base Case
    dp[0] = true;
 
    // Iterate over the characters
    // of the string pattern
    for (let i = 0; i < M; i++) {
        if (pattern[i] === '*' && dp[i - 1]) {
 
            // Update dp[i + 1]
            dp[i + 1] = true;
        }
    }
 
    // Iterate over the characters
    // of both the strings
    for (let i = 0; i < N; i++) {
        let prev = dp[0];
        dp[0] = false;
 
        for (let j = 0; j < M; j++) {
 
            let temp = dp[j+1];
 
            // If current character
            // in the pattern is '.'
            if (pattern[j] === '.') {
 
                // Update dp[j + 1]
                dp[j + 1] = prev;
            }
 
            // If current character in
            // both the strings are equal
            else if (pattern[j] === text[i]) {
 
                // Update dp[j + 1]
                dp[j + 1] = prev;
            }
 
            // If current character
            // in the pattern is '*'
            else if (pattern[j] === '*') {
 
                if (pattern[j - 1] !== text[i]
                    && pattern[j - 1] !== '.') {
 
                    // Update dp[j + 1]
                    dp[j + 1] = dp[j - 1];
                }
 
                else {
 
                    // Update dp[j + 1]
                    dp[j + 1] = (dp[j + 1] || dp[j] || prev);
                }
            }
            else {
 
                // Update dp[j + 1]
                dp[j + 1] = false;
            }
 
            prev = temp;
        }
    }
 
    // Return dp[M]
    return dp[M];
}
 
// Driver Code
let text = "geeksforgeeks";
let pattern = "ge*ksforgeeks";
 
if (isMatch(text, pattern)) {
    console.log("Yes");
} else {
    console.log("No");
}


C#




using System;
 
class GFG {
    // Function to check if the pattern
    // consisting of '*', '.' and lowercase
    // characters matches the text or not
    static bool isMatch(string text, string pattern)
    {
        // Base Case
        if (text == "" || pattern == "") {
            return false;
        }
 
        // Stores length of text
        int N = text.Length;
 
        // Stores length of pattern
        int M = pattern.Length;
 
        // dp[j]: Check if { text[0], .. text[i] }
        // matches {pattern[0], ... pattern[j]} or not
        bool[] dp = new bool[M + 1];
 
        // Base Case
        dp[0] = true;
 
        // Iterate over the characters
        // of the string pattern
        for (int i = 0; i < M; i++) {
            if (pattern[i] == '*' && dp[i - 1]) {
                // Update dp[i + 1]
                dp[i + 1] = true;
            }
        }
 
        // Iterate over the characters
        // of both the strings
        for (int i = 0; i < N; i++) {
            bool prev = dp[0];
            dp[0] = false;
 
            for (int j = 0; j < M; j++) {
                bool temp = dp[j + 1];
 
                // If current character
                // in the pattern is '.'
                if (pattern[j] == '.') {
                    // Update dp[j + 1]
                    dp[j + 1] = prev;
                }
 
                // If current character in
                // both the strings are equal
                else if (pattern[j] == text[i]) {
                    // Update dp[j + 1]
                    dp[j + 1] = prev;
                }
 
                // If current character
                // in the pattern is '*'
                else if (pattern[j] == '*') {
                    if (pattern[j - 1] != text[i]
                        && pattern[j - 1] != '.') {
                        // Update dp[j + 1]
                        dp[j + 1] = dp[j - 1];
                    }
                    else {
                        // Update dp[j + 1]
                        dp[j + 1]
                            = (dp[j + 1] || dp[j] || prev);
                    }
                }
                else {
                    // Update dp[j + 1]
                    dp[j + 1] = false;
                }
 
                prev = temp;
            }
        }
 
        // Return dp[M]
        return dp[M];
    }
 
    static void Main(string[] args)
    {
        string text = "geeksforgeeks";
        string pattern = "ge*ksforgeeks";
 
        if (isMatch(text, pattern)) {
            Console.WriteLine("Yes");
        }
        else {
            Console.WriteLine("No");
        }
    }
}


Output

Yes

Time Complexity: O(M * N), where N is the size of the text string and M is the size of the pattern string
Auxiliary Space: O(M)1, space used for storing DP values



Last Updated : 18 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads