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; } }