正则表达式匹配

正则表达式匹配

正则表达式是一种强大的字符串匹配工具,允许我们根据某种模式来查找、验证和提取字符串。在本文中,我们将探讨如何使用 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

输入: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 代码中演示了如何实现支持 ‘.’ 和 ‘*’ 的正则表达式匹配。希望本文对你理解和解决这个问题有所帮助。如果你有任何问题或疑问,请随时提出。

你可能感兴趣的:(初学篇,正则表达式,力扣)