[10] 正则表达式匹配

复制代码
/**
 * @param {string} s
 * @param {string} p
 * @return {boolean}
 */
var isMatch = function (s, p) {
  if (s == null || p == null) return false;//极端情况 s和p都是空 返回false

  const sLen = s.length, pLen = p.length;

  const dp = new Array(sLen + 1);//因为位置是从0开始的,第0个位置是空字符串 所以初始化长度是sLen + 1
  for (let i = 0; i < dp.length; i++) {//初始化dp数组
    dp[i] = new Array(pLen + 1).fill(false); // 将项默认为false
  }
  // base case s和p第0个位置是匹配的
  dp[0][0] = true;
  for (let j = 1; j < pLen + 1; j++) {//初始化dp的第一列,此时s的位置是0
    //情况1:如果p的第j-1个位置是*,则j的状态等于j-2的状态
    //例如:s='' p='a*' 相当于p向前看2个位置如果匹配,则*相当于重复0个字符
    if (p[j - 1] == "*") dp[0][j] = dp[0][j - 2];
  }
  // 迭代
  for (let i = 1; i < sLen + 1; i++) {
    for (let j = 1; j < pLen + 1; j++) {

      //情况2:如果s和p当前字符是相等的 或者p当前位置是. 则当前的dp[i][j] 可由dp[i - 1][j - 1]转移过来
      //当前位置相匹配,则s和p都向前看一位 如果前面所有字符相匹配 则当前位置前面的所有字符也匹配
      //例如:s='XXXa' p='XXX.' 或者 s='XXXa' p='XXXa'
      if (s[i - 1] == p[j - 1] || p[j - 1] == ".") {
        dp[i][j] = dp[i - 1][j - 1];
      } else if (p[j - 1] == "*") {//情况3:进入当前字符不匹配的分支 如果当前p是* 则有可能会匹配
        //s当前位置和p前一个位置相同 或者p前一个位置等于. 则有三种可能
        //其中一种情况能匹配 则当前位置的状态也能匹配
        //dp[i][j - 2]:p向前看2个位置,相当于*重复了0次,
        //dp[i][j - 1]:p向前看1个位置,相当于*重复了1次
        //dp[i - 1][j]:s向前看一个位置,相当于*重复了n次
        //例如 s='XXXa' p='XXXa*'
        if (s[i - 1] == p[j - 2] || p[j - 2] == ".") {
          dp[i][j] = dp[i][j - 2] || dp[i][j - 1] || dp[i - 1][j];
        } else {
          //情况4:s当前位置和p前2个位置不匹配,则相当于*重复了0次
          //例如 s='XXXb' p='XXXa*' 当前位置的状态和p向前看2个位置的状态相同
          dp[i][j] = dp[i][j - 2];
        }
      }
    }
  }
  return dp[sLen][pLen]; // 长为sLen的s串 是否匹配 长为pLen的p串
};
复制代码

 

posted @   人恒过  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示