zoukankan      html  css  js  c++  java
  • 剑指 Offer 19. 正则表达式匹配

    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];
       }
        
    }
  • 相关阅读:
    Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)(转载)
    sql 去掉 空格
    sqlserver清除缓存(转载)
    sqlsever 科学计数法e 问题
    将一张表中的数据插入到另一张表
    Spark的Driver节点和Executor节点
    实时流计算Spark Streaming原理介绍
    Spark Streaming实战
    Spark 以及 Spark Streaming 核心原理及实践
    SparkSQL读取Hive中的数据
  • 原文地址:https://www.cnblogs.com/jieyi/p/14331639.html
Copyright © 2011-2022 走看看