Leetcode 10. Regular Expression Matching

10. Regular Expression Matching

题目描述

Given an input string (s) and a pattern §, implement regular expression matching with support for ‘.’ and '’.
给出一个字符串s和一个正则模式p,实现一个支持’.’,’
'的正则表达式匹配函数

‘.’ Matches any single character. 匹配任意一个字符
‘*’ Matches zero or more of the preceding element. 表示前字符出现任意次数

注意:
s 可以为空,并且只包含a-z
p 可以为空,并且只包含a-z,’.’,’*’

思路

首先,直接匹配字符或者通配符的匹配都比较简单,关键是这个代表的任意个匹配前一字符比较麻烦。
我们可以维持两个指针i,j,标识两个字符串的匹配进度,如果两者同时到达了字符串终点,那么就可以认为是匹配成功结束。如果其中一方有剩余,或者中途已经无法匹配,那就是匹配失败。
遇到
的时候我们就使用递归调用,从匹配零个,匹配一个,匹配n个,直到无法匹配(即没有相同的前个字符了)

代码

/**
 * @param {string} s
 * @param {string} p
 * @return {boolean}
 */
var isMatch = function (s, p) {
  // 两个字符串s,p,两个长度slen,plen等于是存在外函数里面,等下的所有递归调用的内函数都可以访问。如果写成c的话就要传进去了
  var str = 0, ptr = 0;
  var slen = s.length, plen = p.length;

  // 实际上的递归函数
  function Match(str, ptr) {
    
    //console.log("s: "+str+" ; p: "+ptr);
    if (str > slen) return false;
    if (ptr > plen) return false;
    // 终止条件
    // 两者都结束,或者s结束p剩下的全是x*y*了
    // 现在如果s已经结束,那么我就判断p是否结束或者剩下的全是x*的格式
    if (str == slen) {
      var gap = true;
      // 用一个boolen变量控制一次字符、一次*
      while (ptr != plen) {
        if (gap && p[ptr] != '*' || !gap && p[ptr] == '*') {
          ptr++;
        } else {
          break;
        }
        gap = !gap;
      }
      if (ptr == plen && gap) {
        return true;
      }
    }
    // 递归求值
    else {
      // 如果p的下一个值不是'*',那么直接比较当前值
      if (p[ptr+1] != '*') {
        if (s[str] == p[ptr] || p[ptr] == '.') {
          return Match(str+1, ptr+1);
        } else {
          return false;
        };
      // 下一个值是*就要把ptr,ptr+1一同考虑,然后让他们匹配0到n个字符
      } else {
        // 但是还是有一个比较奇特的地方就是'.',因为他可以匹配任意字符,".*"的话就比较神奇了
        var result = Match(str, ptr + 2);
        while (str < slen && p[ptr] == '.' || s[str] == p[ptr]) {
          result = result || Match(str + 1, ptr + 2);
          str++;
        }
        return result || Match(str, ptr + 2);
      }
    }
    return false;
  }
  // 直接返回函数递归调用的结果好像会出错,弄一个变量先保存在返回好了
  var result = Match(str, ptr);
  return result;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值