zoukankan      html  css  js  c++  java
  • 剑指Offer_#19_正则表达式匹配(待复习)

    剑指Offer_#19_正则表达式匹配(待复习)

    Contents

    题目

    请实现一个函数用来匹配包含'. '和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"和"ab*a"均不匹配。

    示例 1:

    输入:
    s = "aa"
    p = "a"
    输出: false
    解释: "a" 无法匹配 "aa" 整个字符串。

    示例 2:

    输入:
    s = "aa"
    p = "a*"
    输出: true
    解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。

    示例 3:

    输入:
    s = "ab"
    p = ".*"
    输出: true
    解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。

    示例 4:

    输入:
    s = "aab"
    p = "c*a*b"
    输出: true
    解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。

    示例 5:

    输入:
    s = "mississippi"
    p = "mis*is*p*."
    输出: false

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

    思路分析

    这题比较难,目前只看了评论区的高赞题解,不能完全掌握,还需要复习。

    解答

    参考上述题解的代码。
    整体思路是动态规划,即把整个大问题分解为一系列小问题,要看整个s和p是否匹配,可以从后往前,分解为判断s的字串与p的字串是否匹配。
    以上是从上到下分析问题的过程。
    具体编码是从下到上地解决问题。即先解决小问题,依赖小问题,得到大问题的解。
    问题关键在于,不同的情况下,状态转移方程不同,需要准确的写出状态转移方程,捋清楚条件判断分支的逻辑。否则必然会出现一些细节上的错误,无法通过测试。

    public class Solution {
        public static boolean isMatch(String s, String p) {
            int n = s.length();//字符串的长度是length()
            int m = p.length();
            boolean[][] f = new boolean[n + 1][m + 1];//f[i][j]代表 A的前i个字符 与 B的前j个字符 是否匹配
    
            for (int i = 0; i <= n; i++) {
                for (int j = 0; j <= m; j++) {
                    //分为空正则和非空正则两种情况
                    if (j == 0) {
                        //i==0&&j==0时,字符串和空模式串可以匹配,f[i][j]=true
                        //反之,空模式串和非空字符串无法匹配,f[i][j]=false
                        f[i][j] = (i == 0);
                    } else {
                        //非空正则分为末尾是 * 或者 非*
                        if (p.charAt(j - 1) != '*') {//前j个字符的长度是j,其中最后一个字符索引是j - 1
                            if (i > 0 && (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '.')) {
                                f[i][j] = f[i - 1][j - 1];
                            }
                        } else {
                            //末尾是 *,分为有效,无效两种情况(无效也就是说模式串最后的c*匹配到的是0个c)
                            //这里判断 有效/无效 的条件并不明确,所以是将两个分支的结果进行或运算,那么任意一个为true,结果就为true
                            //无效
                            if (j >= 2) {
                                f[i][j] |= f[i][j - 2];//直接跳过模式串最后的 c* 两个字符
                            }
                            //有效
                            if (i >= 1 && j >= 2 && (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.')) {
                                f[i][j] |= f[i - 1][j];
                            }
                        }
                    }
                }
            }
            return f[n][m];
        }
    }

    复杂度分析

    时间复杂度O(mn)
    空间复杂度O(mn)
    其中m,n是字符串p,s的长度。

  • 相关阅读:
    Software Solutions CACHE COHERENCE AND THE MESI PROTOCOL
    CACHE COHERENCE AND THE MESI PROTOCOL
    Multiprocessor Operating System Design Considerations SYMMETRIC MULTIPROCESSORS
    Organization SYMMETRIC MULTIPROCESSORS
    PARALLEL PROCESSING
    1分钟内发送差评邮件
    Secure Digital
    SYMMETRIC MULTIPROCESSORS
    A Taxonomy of Parallel Processor Architectures
    parallelism
  • 原文地址:https://www.cnblogs.com/Howfars/p/13187842.html
Copyright © 2011-2022 走看看