Implement wildcard pattern matching with support for
'?'
and
'*'
.
'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).
The matching should cover the entire input string (not partial).
The function prototype should be:
bool isMatch(const char *s, const char *p)
Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false
public class Solution {
public boolean isMatch(String s, String p) {
// DP can't handle this question because of high time complexity.
// Here we adopt greedy algorithm.
// If matched, continue consider next character of 's'.
// If not matched, find if there is '*' before current character of 'p'.
// If found '*', re-consider if the next element of '*' of 'p' match (mark+1)th element of 's'.
int m = s.length();
int n = p.length();
int i = 0;
int j = 0;
int mark = -1; // Mark character of 's' when encounter '*'.
int star = -1; // Store index of last '*'.
while (i < m)
{
// If matched, continue consider next character of 's'.
if (j<n && (s.charAt(i)==p.charAt(j) || p.charAt(j)=='?'))
{
i++;
j++;
}
// Mark '*' and continue using next character of 'p' to match current character of 's'.
else if (j<n && p.charAt(j) == '*')
{
mark = i;
star = j++;
}
// It represents there is '*' before current character of 'p'
else if (star != -1)
{
i = ++mark; // Next try will skip current mark (In other words, use '*' cover current 'mark').
j = star+1;
}
// Not matched
else
return false;
}
// When 's' has been reached end, there are still some characters of 'p' unchecked.
// They must be '*' if 'p' match 's'.
while (j<n && p.charAt(j)=='*')
j++;
// If don't find any unmatched character until 's' and 'p' both reach end, return true.
return j == n;
}
}
No comments:
Post a Comment