package jianzhioffer;

public class test19 {
    public static void main(String[] args) {
        
    }
    /**
     * 如果 BB 的最后一个字符是正常字符,那就是看 A[n-1]A[n−1] 是否等于 B[m-1]B[m−1],相等则看 A_{0..n-2}A 
0..n−2
​    
  与 B_{0..m-2}B 
0..m−2
​    
 ,不等则是不能匹配,这就是子问题。

如果 BB 的最后一个字符是.,它能匹配任意字符,直接看 A_{0..n-2}A 
0..n−2
​    
  与 B_{0..m-2}B 
0..m−2
​    
 

如果 BB 的最后一个字符是*它代表 B[m-2]=cB[m−2]=c 可以重复0次或多次,它们是一个整体 c*c∗

情况一:A[n-1]A[n−1] 是 00 个 cc,BB 最后两个字符废了,能否匹配取决于 A_{0..n-1}A 
0..n−1
​    
  和 B_{0..m-3}B 
0..m−3
​    
  是否匹配
情况二:A[n-1]A[n−1] 是多个 cc 中的最后一个(这种情况必须 A[n-1]=cA[n−1]=c 或者 c='.'c= 
′
 . 
′
 ),所以 AA 匹配完往前挪一个,BB 继续匹配,因为可以匹配多个,继续看 A_{0..n-2}A 
0..n−2
​    
  和 B_{0..m-1}B 
0..m−1
​    
 是否匹配。
转移方程
f[i] [j]f[i][j] 代表 AA 的前 ii 个和 BB 的前 jj 个能否匹配

对于前面两个情况,可以合并成一种情况 f[i][j] = f[i-1][j-1]f[i][j]=f[i−1][j−1]

对于第三种情况,对于 c*c∗ 分为看和不看两种情况

不看:直接砍掉正则串的后面两个, f[i][j] = f[i][j-2]f[i][j]=f[i][j−2]
看:正则串不动,主串前移一个,f[i][j] = f[i-1][j]f[i][j]=f[i−1][j]
初始条件
特判:需要考虑空串空正则

空串和空正则是匹配的,f[0][0] = truef[0][0]=true
空串和非空正则,不能直接定义 truetrue 和 falsefalse,必须要计算出来。(比如A=A= '' '' ,B=a*b*c*B=a∗b∗c∗)
非空串和空正则必不匹配,f[1][0]=...=f[n][0]=falsef[1][0]=...=f[n][0]=false
非空串和非空正则,那肯定是需要计算的了。
     * @param s
     * @param p
     * @return
     */
    public boolean isMatch(String s, String p) {
        int n=s.length();
       int m=p.length();
       boolean [][]f=new boolean[n+1][m+1];
       for(int i=0;i<=n;i++){
           for(int j=0;j<=m;j++){
               if(j==0){
                   f[i][j]=(i==0);
               }else{
                   if(p.charAt(j-1)!='*'){
                       if(i>0&&(s.charAt(i-1)==p.charAt(j-1)||p.charAt(j-1)=='.')){
                           f[i][j]=f[i-1][j-1];
                       }
                   }else{
                       if(j>=2){
                           f[i][j]|=f[i][j-2];
                       }
                       if(i>=1&&j>=2&&(s.charAt(i-1)==p.charAt(j-2)||(p.charAt(j-2)=='.'))){
                           f[i][j]|=f[i-1][j];
                       }
                   }
               }
           }
       }
       return f[n][m];
   }
    
}