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
dynamic programming code
public class Solution {
public boolean isMatch(String s, String p) {
//check the characters in p which is not *
int count = 0;
for(int i = 0; i < p.length(); ++i)
count += (p.charAt(i) == '*') ? 0 : 1;
if(count > s.length())
return false;
boolean[][] matchChecked = new boolean[s.length() + 1][p.length() + 1];
matchChecked[0][0] = true;
for(int i = 1; i < s.length() + 1; ++i)
matchChecked[i][0] = false;
for(int i = 1; i < p.length() + 1; ++i)
matchChecked[0][i] = matchChecked[0][i - 1] && (p.charAt(i - 1) == '*');
for(int i = 1; i < s.length() + 1; ++i) {
for(int j = 1; j < p.length() + 1; ++j) {
if(p.charAt(j - 1) == '*')
matchChecked[i][j] = matchChecked[i - 1][j - 1] || matchChecked[i - 1][j] || matchChecked[i][j - 1];
else
matchChecked[i][j] = (matchChecked[i - 1][j - 1] && (p.charAt(j - 1) == '?'))
|| (matchChecked[i - 1][j - 1] && (p.charAt(j - 1) == s.charAt(i - 1)));
}
}
return matchChecked[s.length()][p.length()];
}
}
another code:
public class Solution {
public boolean isMatch(String s, String p) {
int slen = s.length(), plen = p.length();
int start = Integer.MAX_VALUE, resume = 0;
int i = 0, j = 0;
while(i < slen){
//remove the *'s in roll, keep the index of i for resume the further outer loop
while(j< plen && p.charAt(j) == '*'){
start = j;
++j;
resume = i;
}
//when j reach the end of the string p and
if(j == plen ||(p.charAt(j) != s.charAt(i) && p.charAt(j) != '?')){
//if there is no * in p, then these two strings are not matched under the above
//condition
if(start > plen)
return false;
//if there is a * in p, we need ignore some characters in s and resume comparison.
else{
j = start + 1;
++resume; //This is important, we need to resume the comparsion from each
//possible position after i
i = resume;
}
}
//when two strings are same at theses positions. move i and j forward simultanenously.
else{
++i;
++j;
}
}
//Once we exhausted the string s, we need to check whether p reaches its end
while(j < plen && p.charAt(j) == '*')
++j;
return j == plen;
}
}