Wildcard Matching

To solve this coding challenge of wildcard matching, where we need to determine if a given input string matches a pattern that includes special characters '?' and ' ', we can use dynamic programming (DP). The '?' character matches any single character, and the ' ' character matches any sequence of characters (including the empty sequence). Our task is to check if the entire string matches the pattern. Using dynamic programming, we can break this problem into smaller subproblems and use their solutions to solve the larger problem. The core idea is to create a 2D DP table where
dp[i][j]
indicates whether the substring
s[0...i-1]
matches the subpattern
p[0...j-1]
.
Here's a detailed explanation and pseudocode to solve this challenge:
# Explanation
  1. Initialize a DP Table : Create a 2D list
    dp
    where
    dp[i][j]
    will hold boolean values representing whether the first
    i
    characters of the string
    s
    match the first
    j
    characters of the pattern
    p
    . The dimensions of this table will be
    (len(s) + 1) x (len(p) + 1)
    .
  2. Base Case :
    • dp[0][0]
      should be
      True
      because an empty pattern matches an empty string.
    • Initialize the first row based on whether the pattern up to that point consists solely of ' ' characters, as ' ` can match an empty sequence.
  3. Filling the DP Table :
    • Iterate over each character in the string
      s
      and the pattern
      p
      .
    • If the current character in the pattern is '*', update the DP table considering two cases:
      • The '*' matches zero characters in
        s
        (carry forward the result from the left cell).
      • The '*' matches one character or more in
        s
        (carry forward the result from the above cell).
    • If the current character in the pattern is '?', or if it matches the current character in
      s
      , update the DP table by carrying forward the result from the diagonal cell.
  4. Result : The value in
    dp[len(s)][len(p)]
    will tell us whether the entire string
    s
    matches the pattern
    p
    .
Detailed Steps in Pseudocode
                                            
# Initialize Variables
s = "..."
p = "..."
len_s = length of s
len_p = length of p

# Create a 2D DP table initialized to False
dp = 2D list of size (len_s + 1) x (len_p + 1) initialized to False

# Base Case: An empty pattern matches an empty string
dp[0][0] = True

# Handle patterns starting with '*' that can match an empty sequence
for j from 1 to len_p:
    if pattern[j - 1] is '*':
        dp[0][j] = dp[0][j - 1]

# Iterate over each character in the string and the pattern
for i from 1 to len_s:
    for j from 1 to len_p:
        if pattern[j - 1] is '*':
            # '*' matches zero characters or one/more characters
            dp[i][j] = dp[i][j - 1] or dp[i - 1][j]
        elif pattern[j - 1] is '?' or string[i - 1] is equal to pattern[j - 1]:
            # '?' matches any single character or characters match
            dp[i][j] = dp[i - 1][j - 1]

# Result is whether the entire string matches the pattern
return dp[len_s][len_p]

                                        
Step-by-Step Explanation
  • Initialize the
    dp
    table
    : The table is a 2D list of size
    (len(s) + 1) x (len(p) + 1)
    initialized to
    False
    , except
    dp[0][0]
    which is
    True
    because an empty string matches an empty pattern.
  • Fill the first row : This row (`dp[0][j]`) tracks the pattern matching an empty string. It can only be `True` if the pattern consists only of `' '
    characters up to that point. Hence, if
    p[j-1]
    is
    '
    '`, we set `dp[0][j] = dp[0][j-1]`.
  • Nested loops to fill the table :
    • For each character
      i
      in the string
      s
      and each character
      j
      in the pattern
      p
      , we examine the characters in
      s
      and
      p
      .
    • If
      p[j-1]
      is
      '*'
      , we update
      dp[i][j]
      based on:
      • dp[i][j-1]
        (if
        '*'
        counts as matching zero characters).
      • dp[i-1][j]
        (if
        '*'
        counts as matching one or more characters).
    • If
      p[j-1]
      is
      ?
      or
      s[i-1] == p[j-1]
      , we update
      dp[i][j]
      based on
      dp[i-1][j-1]
      .
  • Final Result : After filling the table,
    dp[len(s)][len(p)]
    contains the answer, indicating whether the entire string matches the pattern.