剑指Offer——正则表达式匹配(JS实现)

简介: 剑指Offer——正则表达式匹配(JS实现)

题目描述

image.png

解题思路

  • 本题的主流解法包括两种,主要是递归回溯与动态规划,鉴于动态规划不易理解,本文采用递归回溯的方法进行讲解,步骤如下:

1. 判断p字符串是否为空,如果为空则继续判断字符串s是否为空

  • 我们首先要准确理解字符s和字符p的含义,字符s代表的是待匹配的字符串,而字符串p则代表的是我们的匹配模式
  • 如果匹配模式为空,我们要看待匹配的字符s是否为空,如果两者皆为空,说明空匹配空,结果返回true,如果p为空,但是s不为空,说明让空去匹配非空,肯定false,这是我们递归的出口。
if (p.length === 0) {
    if (s.length === 0) {
        return true;
    } else {
        return false;
    }
}

2. 判断在字符串s非空的情况下,第一个字符是否能够成功匹配

  • 为什么要在字符串s非空的情况下,去进行匹配?

答:因为字符串s如果为空,去匹配第一个字符是没有意义的,如果字符s为空,且能够走到这里,说明字符串p不为空,要不然也不能走到第二步就返回了,如果字符s为空我们跳转到后面的第三步。

  1. s的第一个字符和p的第一个字符相等,或者p的第一个字符为 ".",都说明成功匹配到了。
  2. 判断字符串p的长度,此时存在两种情况,一种是小于2,一种是大于等于2,如果小于2,我们就没必要判断当前字符p的第二个字符是不是*号了,直接将s去掉首元素和p去掉首元素,投入到递归函数中去继续判断,如果大于等于2的情况,则是有必要继续判断的,我们要判断p字符的第二个字符是不是*号的,如果第二个是*号则存在两种情况,一个是这个*号代表前面的字符出现了0次,另一种情况是前面的字符出现了多次,此时我们就要分情况讨论了,如果代表的是0次,则将s不变和p去掉前两个字符,投入递归函数,如果代表的是多次,我们首先当作一次,把s去掉首元素,p不变继续递归。
  3. 如果字符串p的长度小于2,由于前面的条件限制使得首元素是相同的,我们只用将s和p分别去掉首元素,继续投入递归,由结束条件来帮助我们继续判断。
  4. 如果字符串s为空,或者第一个字符不匹配,我们首先判断p的长度,如果p的长度是小于2的,当前元素不同,后面又没有*了,所以直接返回false,如果p的长度是大于等于2的,继续判断p的第二个元素是不是*,如果是,则将s不变,p去掉两个首元素继续递归判断,如果第二个元素不是*,直接返回false.

解题代码

var isMatch = function (s, p) {
    // 判断模式p是否为空,如果为空,则判断s是否为空
    if (p.length === 0) {
        if (s.length === 0) {
            return true;
        } else {
            return false;
        }
    }
    // 判断第一个字符是否匹配
    if (s.length !== 0 && (s[0] === p[0] || p[0] === '.')) {
        // 走到这里说明,第一个字符是匹配的
        if (p.length >= 2) {
            // 判断第二个字符是不是 *
            if (p[1] === '*') {
                return isMatch(s, p.slice(2)) || isMatch(s.slice(1), p)
            } else {
                return isMatch(s.slice(1), p.slice(1));
            }
        } else {
            return isMatch(s.slice(1), p.slice(1));
        }
    } else {
        if (p.length >= 2) {
            if (p[1] === '*') {
                return isMatch(s, p.slice(2));
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
};

总结(本题给我们的启示思路)

  • 学会通过递归回溯解决多边界条件问题
  • 本题的难点在于*这种情况的考虑,刚开始不会也是正常,千万不要焦躁,不要放弃,仔细想想总会解出来的。
相关文章
|
2月前
|
存储 JSON JavaScript
「offer来了」保姆级巩固你的js知识体系(4.0w字)
该文章提供了JavaScript知识体系的全面复习资料,覆盖了从基础语法到高级特性如闭包、原型链、异步编程等多个方面,并通过大量的面试题和实例代码帮助巩固理解。
「offer来了」保姆级巩固你的js知识体系(4.0w字)
|
1月前
|
JavaScript 前端开发
电话号码正则表达式 代码 javascript+html,JS正则表达式判断11位手机号码
电话号码正则表达式 代码 javascript+html,JS正则表达式判断11位手机号码
110 1
|
2月前
|
自然语言处理 JavaScript 前端开发
JavaScript 正则表达式
JavaScript 正则表达式
18 3
|
3月前
|
JavaScript 前端开发
js中通过正则表达式验证邮箱是否合法
这篇文章提供了一个JavaScript示例,通过正则表达式在网页上验证用户输入的邮箱地址是否合法,并给出了相应的提示信息。
js中通过正则表达式验证邮箱是否合法
|
5月前
|
机器学习/深度学习 JavaScript 前端开发
JavaScript中的正则表达式详细展示
JavaScript中的正则表达式详细展示
39 6
|
5月前
|
JavaScript 前端开发 测试技术
JavaScript进阶-正则表达式基础
【6月更文挑战第21天】正则表达式是处理字符串的利器,JavaScript中广泛用于搜索、替换和验证。本文讲解正则基础,如字符匹配、量词和边界匹配,同时也讨论了常见问题和易错点,如大小写忽略、贪婪匹配,提供代码示例和调试建议。通过学习,开发者能更好地理解和运用正则表达式解决文本操作问题。
47 1
|
4月前
|
JavaScript 数据安全/隐私保护
js 常用正则表达式【实用】
js 常用正则表达式【实用】
26 0
|
4月前
|
存储 JavaScript 前端开发
|
5月前
|
XML JavaScript 数据安全/隐私保护
一篇文章讲明白js常用js正则表达式大全
一篇文章讲明白js常用js正则表达式大全
34 0
|
6月前
|
前端开发 JavaScript
前端 js 经典:正则表达式
前端 js 经典:正则表达式
56 2