• 正则表达式匹配


    正则表达式匹配

    正则表达式是一种强大的字符串匹配工具,允许我们根据某种模式来查找、验证和提取字符串。在本文中,我们将探讨如何使用 Java 来实现支持 ‘.’ 和 ‘*’ 的正则表达式匹配,其中:

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

    这个问题的关键在于理解 ‘*’ 的含义以及如何构建匹配规则。我们将使用动态规划来解决这个问题。

    动态规划解决方案

    动态规划是解决此类字符串匹配问题的一种强大方法。我们可以使用一个二维布尔数组 dp,其中 dp[i][j] 表示字符串 s 的前 i 个字符和模式 p 的前 j 个字符是否匹配。接下来,让我们逐步构建解决方案。

    初始化

    首先,我们需要初始化 dp 数组。考虑以下情况:

    • dp[0][0] 表示空字符串和空模式,它们是匹配的,所以 dp[0][0] = true
    • dp[i][0] 表示非空字符串与空模式,它们永远不会匹配,所以 dp[i][0] = false
    • dp[0][j] 表示空字符串与非空模式,此时我们需要考虑 * 号的情况,如果 p[j-1]*,则可以消除前一个字符,即 dp[0][j] = dp[0][j-2]

    状态转移

    接下来,我们需要考虑 dp[i][j] 的状态转移。我们可以根据 s[i-1]p[j-1] 来决定 dp[i][j] 的值。

    1. 如果 s[i-1]p[j-1] 匹配(或 p[j-1].),则 dp[i][j] 取决于 dp[i-1][j-1],即 dp[i][j] = dp[i-1][j-1]
    2. 如果 p[j-1]*,则需要考虑 * 号的两种用法:
      • * 匹配零次前面的字符,即 dp[i][j] = dp[i][j-2]
      • * 匹配一次或多次前面的字符,即 s[i-1]p[j-2] 匹配,并且 dp[i][j] 取决于 dp[i-1][j],即 dp[i][j] = dp[i-1][j]

    实现代码

    根据上述思路,我们可以实现如下的 Java 代码:

    class Solution {
        public boolean isMatch(String s, String p) {
            int m = s.length();
            int n = p.length();
            boolean[][] dp = new boolean[m + 1][n + 1];
            
            // 初始化
            dp[0][0] = true;
            for (int j = 1; j <= n; j++) {
                if (p.charAt(j - 1) == '*') {
                    dp[0][j] = dp[0][j - 2];
                }
            }
            
            // 状态转移
            for (int i = 1; i <= m; i++) {
                for (int j = 1; j <= n; j++) {
                    if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '.') {
                        dp[i][j] = dp[i - 1][j - 1];
                    } else if (p.charAt(j - 1) == '*') {
                        dp[i][j] = dp[i][j - 2] || (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.') && dp[i - 1][j];
                    }
                }
            }
            
            return dp[m][n];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    示例

    现在让我们来测试一些示例来验证我们的实现是否正确。

    示例 1

    输入:s = “aa”, p = “a”
    输出:false

    这是一个简单的示例,因为模式 p 中的字符和字符串 s 中的字符无法匹配。所以返回 false

    示例 2

    输入:s = “aa”, p = “a*”
    输出:true

    在这个示例中,由于 * 可以匹配零个或多个前面的字符,字符串 “aa” 可以被视为 ‘a’ 重复了一次。所以返回 true

    示例 3

    输入:s = “ab”, p = “.*”
    输出:true

    模式 “.*” 可以匹配零个或多个任意字符,所以它可以匹配字符串 “ab”。返回 true

    结论

    正则表达式匹配是一个有趣且复杂的问题,但通过使用动态规划,我们可以有效地解决它。我们在上面提供的 Java 代码中演示了如何实现支持 ‘.’ 和 ‘*’ 的正则表达式匹配。希望本文对你理解和解决这个问题有所帮助。如果你有任何问题或疑问,请随时提出。

  • 相关阅读:
    Java swing实现应用程序对数据库的访问
    Markdown 和 LaTeX 写作规范(持续更新,建议收藏)
    Cluster API 检索从未如此简单
    Peer Dependency 一些使用场景的归纳总结
    2022年企业和站长租用服务器的几个常见误区
    openpnp - 接入西门子二手飞达
    [附源码]计算机毕业设计基于springboot的小区宠物管理系统
    36李沐动手学深度学习v2/图像增广
    全球创业浪潮:跨境电商的创新时代
    OpenLayers-要素属性信息简单弹窗
  • 原文地址:https://blog.csdn.net/weixin_51151534/article/details/133949082