请实现一个函数用来匹配包含’. ‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但与"aa.a"和"ab*a"均不匹配。
s串和p串比较是否匹配,可以通过逐次比较每个字符是否相等,因此可以通过动态规划记录比较的结果。
动态规划
设f[n][m]为S的前n个字符和P的前m个字符的匹配结果
字符串Sn的长度为n,字符串Pm的长度为m
1、如果pm-1==’’,则可以和前面的字符成组合,要么0个,要么2个字符串组合变成一个或多个。
①0个,f[n][m]=f[n][m-2](直接将这两个字符拿掉) S:aa P:aaa,直接将"a*“拿掉就匹配
②1个,这种情况得判断Sn和Pm-1是否匹配,匹配的话,就可以将Sn去掉,f[n][m]=f[n-1][m]() S:aab P:aab*
③多个, S:aabbbbbb P:aab*,这种情况就是跟②一样,如果S的最后一个字符跟P的” * "前面的字符一样,将S的最后一个字符去掉,然后继续比较f[n][m]=f[n-1][m],f[n][m]=f[n-2][m]…直到相同的字符比较完,就变为①这种情况。
因此,如果Sn==Pm-1 ,f[n][m]=f[n-1][m]||f[n][m-2],否则f[n][m]=f[n][m-2]
2、如果pm-1!=’*’,直接比较Sn==Pm,相等的话,
f[n][m]=f[n-1][m-1]
class Solution {
public boolean isMatch(String s, String p) {
int n=s.length(),m=p.length();
boolean[][] dp=new boolean[n+1][m+1];
dp[0][0]=true;
for(int i=0;i<=n;i++)
for(int j=1;j<=m;j++){
if(p.charAt(j-1)=='*'){
dp[i][j]=dp[i][j-2];
if(check(s,p,i,j-1)){
dp[i][j]=dp[i][j]||dp[i-1][j];
}
}
else{
if(check(s,p,i,j))
dp[i][j]=dp[i-1][j-1];
}
}
return dp[n][m];
}
private boolean check(String s, String p, int i, int j) {
if(i==0) return false;
if(p.charAt(j-1)=='.') return true;
return s.charAt(i-1)==p.charAt(j-1);
}
}