博客
关于我
LeetCode.10 Regular Expression Matching (正则表达式匹配)
阅读量:707 次
发布时间:2019-03-17

本文共 1904 字,大约阅读时间需要 6 分钟。

为了实现支持 '.' 和 '*' 的正则表达式匹配,我们可以利用动态规划来在 O(n) 的时间复杂度内完成任务,其中 n 是输入字符串的长度。动态规划法能有效处理边界情况,并确保整个输入被完全匹配。

解题思路

  • 初始化数组:创建一个大小为 n+1 的布尔数组 dp,其中 dp[i] 表示前 i 个字符是否能够与模式的前 i 个字符完全匹配。初始化 dp[n]true,表示当输入完全被匹配时,状态为 true

  • 从后到前处理模式字符:遍历模式字符串的每个字符,从最后一个字符到第一个字符。根据当前字符的类型,更新 dp 数组:

    • 遇到星号 '*':将 dp[i-1] 的状态与当前状态合并,确保匹配尽可能多的字符。
    • 遇到普通字符:检查输入字符串的对应位置是否与模式字符匹配(包括 '.' 代表的任意字符),并更新状态。
  • 处理边界情况:确保在处理每个字符之前和之后,状态转移逻辑正确,避免遗漏边界条件。

  • 动态规划状态转移

    • 全匹配状态:当 dp[j]dp[j+1] 都为 true 时,表示当前匹配状态有效。
    • 星号处理:星号允许匹配任意数量,包括零个或多个,因此只要后续状态有效,当前状态就可以设置为 true
    • 具体字符匹配:检查当前字符是否等于输入字符串的对应字符或是 '.'。

    代码实现

    public class Solution {    public boolean isMatch(String s, String p) {        int n = s.length();        int m = p.length();        // 处理特殊情况:空模式或空字符串不匹配        if (m == 0 || n == 0) {            return m == n && p.isEmpty() && s.isEmpty();        }        // 创建动态规划数组        boolean[] dp = new boolean[n + 1];        dp[n] = true; // 初始化,全匹配的情况        // 从后向前处理每个字符        for (int j = m - 1; j >= 0; j--) {            // 当前字符来自模式            char c = p.charAt(j);            // 当前处理的是第j个字符,要影响到dp[j+1]            if (c == '*') {                // 星号的情况,我们可以把dp[j]设为dp[j] || dp[j+1]                dp[j] = dp[j] || dp[j + 1];            } else {                // 非星号的情况,只能从前往后检查                if (j + 1 > n) {                    // 当前处理到字符时,已经超出字符串长度                    dp[j] = dp[j + 1];                } else {                    char sc = s.charAt(j);                    dp[j] = dp[j + 1] && ((sc == c) || (sc == '.');                    // 注意这里的逻辑是当前字符要和模式字符或.匹配                }            }        }        // 处理最后的特殊情况,比如:        // 当j =0时,要看是否整个字符串都被匹配        // 特别是,当p不是以星号结尾的时候,可能有的边界情况        return dp[0];    }}

    代码解释

    • 初始化处理:创建 dp 数组,并将最后一个状态设置为 true,表示输入已完全匹配。
    • 倒序遍历模式字符串:从模式的最后一个字符开始处理,检查每个字符的类型,并根据类型更新 dp 数组。
    • 处理星号字符:如果当前字符是星号,状态转移较为复杂,需要综合前后状态。
    • 处理普通字符:检查当前字符是否能与输入字符串中的对应字符匹配,更新状态为 truefalse

    这种方法确保了在每个步骤中正确处理所有可能的匹配情况,从而实现完整的正则表达式匹配。

    转载地址:http://vdjez.baihongyu.com/

    你可能感兴趣的文章
    MySQL 常见的开放性问题
    查看>>
    Mysql 常见错误
    查看>>
    mysql 常见问题
    查看>>
    MYSQL 幻读(Phantom Problem)不可重复读
    查看>>
    mysql 往字段后面加字符串
    查看>>
    mysql 快速自增假数据, 新增假数据,mysql自增假数据
    查看>>
    Mysql 批量修改四种方式效率对比(一)
    查看>>
    Mysql 报错 Field 'id' doesn't have a default value
    查看>>
    MySQL 报错:Duplicate entry 'xxx' for key 'UNIQ_XXXX'
    查看>>
    Mysql 拼接多个字段作为查询条件查询方法
    查看>>
    mysql 排序id_mysql如何按特定id排序
    查看>>
    Mysql 提示:Communication link failure
    查看>>
    mysql 插入是否成功_PDO mysql:如何知道插入是否成功
    查看>>
    Mysql 数据库InnoDB存储引擎中主要组件的刷新清理条件:脏页、RedoLog重做日志、Insert Buffer或ChangeBuffer、Undo Log
    查看>>
    mysql 数据库中 count(*),count(1),count(列名)区别和效率问题
    查看>>
    mysql 数据库备份及ibdata1的瘦身
    查看>>
    MySQL 数据库备份种类以及常用备份工具汇总
    查看>>
    mysql 数据库存储引擎怎么选择?快来看看性能测试吧
    查看>>
    MySQL 数据库操作指南:学习如何使用 Python 进行增删改查操作
    查看>>
    MySQL 数据库的高可用性分析
    查看>>