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 {
/**
* 这个方法用的是动态规划的方法,即针对? * 和普通字符建立一个矩阵,表示其转移
* 初始0,0位置匹配
* 对于每一个位置:
* 如果是Pattern为*,那么当前位置可以匹配到的条件是,只要他的左边 上边 或者左上 任意有一个可以到就可以了
* abcdef a*df
* 如果当前位置是* 那么考虑之前的位置,
<span style="white-space:pre"> </span>(1)这个*可能不是第一次匹配(*上次跟b匹配,这次跟c匹配)如果它能匹配到i的前一个字符(b),那么一定能到这个字符(c) 这是到达它左边的情况
<span style="white-space:pre"> </span>(2)这个*是第一次匹配,就是一般的情况a匹配了a 这次是*无论对应位置是什么都可以匹配成功 这是到达左上的情况
<span style="white-space:pre"> </span> (3) *可以不做任何匹配,如:ab ab* 这是成功匹配的,这时候就是*之前的一个字符已经成功匹配到*现在对应的s字符串中的字符 这是到达它边的情况
* 如果是?或相等,那么条件就是左上可以访问到
* 如果不是,那么就证明不可以访问到了
*
* */
public boolean isMatch(String s, String p) {
char S[]=s.toCharArray();
char P[]=p.toCharArray();
int n=S.length,m=P.length;
boolean dp[][]=new boolean[m+1][n+1];
dp[0][0]=true;
int start=0; //当前对于每行搜索的时候起始位置的标示,一定不用搜索的位置就是每当Pattern遇到一个非*的地方就可以加1
<span style="white-space:pre"> </span>//核心意思就是第一个字符串已经匹配到第start个字符了,再比较的时候可以不用比较start之前的字符了 可以将start省去,下面循环从i开始
for(int i=1;i<=m;i++){ //pattern
if(P[i-1]=='*') {
dp[i][0] = dp[i-1][0];
for(int j=1;j<=n;j++)
dp[i][j] = dp[i-1][j-1] || dp[i][j-1] || dp[i-1][j];
}
else{
// start++;
for(int j=1;j<=n;j++){ //for(int j=start;j<=n;j++){
if(P[i-1]=='?' || P[i-1]==S[j-1]){
if(dp[i-1][j-1] == true) //可以访问
dp[i][j]=true;
}
}
}
}
return dp[m][n];
}
}
比较难理解 变成了一个二维数组的动态规划,这个转移方程确实wocao