美文网首页
leetcode010-匹配正则表达式

leetcode010-匹配正则表达式

作者: 陆阳226 | 来源:发表于2020-05-02 17:33 被阅读0次

问题描述

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。

'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素

所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

说明:

s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。

解答

暴力匹配,使用递归进行回溯

如果只需两个字符串比较,遍历比较即可:

if(s.charAt(i) == p.charAt(i))

如果正则表达式只有 '.' 一个符号,也只需遍历比较即可:

if(s.charAt(i) == p.charAt(i) || p.charAt(i) == '.')

由于 '*' 符号的特殊匹配:匹配0个或多个之前的一个元素

  1. 匹配0个:保持s不变,p减去前两个字符,继续递归
  2. 匹配多个:首先判断首字符是否匹配,如果匹配,s减去首字符,继续递归

综合以上两种情况进行判断

public static boolean isMatch(String s, String p) {
    if (p.isEmpty()) {
        return s.isEmpty();
    }
    // 判断首字符是否匹配
    boolean firstMatch = (!s.isEmpty() && (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.'));
    // 遇到 '*' 符号的两种情况的递归结果取或
    if (p.length() >= 2 && p.charAt(1) == '*') {
        return (isMatch(s, p.substring(2)) || (firstMatch && isMatch(s.substring(1), p)));
    } else {
        // 非 '*' 的情况,在首字符匹配时继续递归
        return firstMatch && isMatch(s.substring(1), p.substring(1));
    }
}

动态规划

创建dp[s.length+1][p.length+1]的数组,存储暴力法中递归子过程的结果,避免暴力法中递归的重复计算
dp[0][0]表示匹配完的结果,dp[s.length][p.length]表示s和p为空时的匹配结果
核心的判断逻辑和暴力法相同

public static boolean isMatch1(String s, String p) {
    boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
    // s、p都为空返回true
    dp[s.length()][p.length()] = true;
    // 自底向上模拟递归的回溯,将结果存储在dp数组中
    for (int i = s.length(); i >= 0; i--) {
        for (int j = p.length() - 1; j >= 0; j--) {
            boolean firstMatch = (i > 0 && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.'));
            if (j + 1 < p.length() && p.charAt(j + 1) == '*') {
                // 当i=s.length()时,firstMatch会使dp[i+1][j]短路,所以不会出现数组越界的问题
                dp[i][j] = dp[i][j + 2] || firstMatch && dp[i + 1][j];
            } else {
                dp[i][j] = firstMatch && dp[i+1][j+1];
            }
        }
    }

    return dp[s.length()][p.length()];
}

相关文章

  • leetcode010-匹配正则表达式

    问题描述 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。 所谓...

  • Nginx 匹配规则

    无 :默认匹配,普通匹配 = :精确匹配 ~* :匹配正则表达式,不区分大小写 ~ :匹配正则表达式,区分大小写 ...

  • 2019.8.15分享:正则表达式字符匹配攻略

    一、正则表达式 正则表达式是匹配模式,要么匹配字符,要么匹配位置。 这次分享主要将提下正则表达式字符匹配 • 两种...

  • python与正则表达式 2020-01-02(未经允许,禁止转

    正则表达式 正则表达式与程序语言无关。正则表达式做匹配实际上就做3件事:【字符匹配】+【次数匹配】+【逻辑匹配】下...

  • 《javaScript正则表达式迷你书》(一)

    正则表达式字符匹配攻略 正则表达式是匹配模式,要么匹配字符,要么匹配位置。 两种模糊匹配 如果正则只有精确匹配是没...

  • 正则加^$与不加的区别

    加^$的正则表达式,表示完整匹配。 正则表达式匹配内容匹配结果说明/bc/abcdefg成功包含就能匹配成功/^a...

  • 正则表达式收集

    常用正则表达式大全 常用正则表达式大全!(例如:匹配中文、匹配html) 匹配中文字符的正则表达式:[u4e00-...

  • 正则表达式位置匹配攻略

    来源:正则表达式位置匹配攻略作者:老姚(转载已获得作者授权) 正则表达式是匹配模式,要么匹配字符,要么匹配位置。 ...

  • 正则表达式字符匹配攻略

    来源:正则表达式字符匹配攻略作者:老姚(转载已获得作者授权) 正则表达式是匹配模式,要么匹配字符,要么匹配位置。请...

  • 5: 正则表达式 + 三剑客之grep

    3 正则表达式 正则表达式元字符分类: 字符匹配 次数匹配 位置锚定 分组 基本正则表达式: vim, grep,...

网友评论

      本文标题:leetcode010-匹配正则表达式

      本文链接:https://www.haomeiwen.com/subject/omakghtx.html