• 剑指 Offer 19. 正则表达式匹配


    剑指 Offer 19. 正则表达式匹配

    题目

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

    示例 1:

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

    思路

    这里为了好理解假设 s 和 p 的索引都是从1开始的

    注意:s的长度一定要从0开始枚举,因为p有可能会匹配空字符串

    • 状态:设 f[i][j] 表示 s 的前 i 个字符 和 p 的前 j 个字符是否匹配
    • 转移
      • p[j] 为普通字符或 .
        • f[i][j] = f[i-1][j-1] (s[i] == p[j] || p[j] == '.')
        • f[i][j] = false (s[i] != p[j])
      • p[j]*
        • 星号前字符重复0次:f[i][j] = f[i][j-2]
        • 星号前字符重复1次:f[i][j] = f[i-1][j-2], (s[i] == p[j-1])
        • 星号前字符重复2次:f[i][j] = f[i-3][j-2], (s[i]==s[i-1]==p[j-1])
        • ...
    • 优化:对于p[j]*的情况,我们要枚举这个组合到底匹配了 s 中的几个字符
      • f[i][j] = f[i-1][j] (s[i] == p[j-1])
      • f[i][j] = f[i][j-2] (s[i] != p[j-1])

    代码

    class Solution {
    public:
        bool isMatch(string s, string p) {
            int m = s.size();
            int n = p.size();
            auto matches = [&](int i, int j) {
                if (i == 0) {
                    return false;
                }
                if (p[j-1] == '.') {
                    return true;
                }
                return s[i-1] == p[j-1];
            };
    
            int f[m+1][n+1];
            memset(f, 0, sizeof(f));
            f[0][0] = true;
            for (int i = 0; i <= m; ++i) { // 外层循环一定要是原始字符串(好像也不一定?)
                for (int j = 1; j <= n; ++j) {
                    if (p[j-1] == '*') {
                        f[i][j] |= f[i][j-2]; // 相当于重复 0 次
                        if (matches(i, j-1)) { // 重复 n 次
                            f[i][j] |= f[i-1][j];
                        }
                    }
                    else {
                        if (matches(i, j)) {
                            f[i][j] |= f[i-1][j-1];
                        }
                    }
                }
            }
            return f[m][n];
        }
    
    };
    
  • 相关阅读:
    Hashtable,挺爽的一个东西,大家都用烂了吧,我再画蛇添足一下。
    今天你写控件了吗?ASP.net控件开发系列(八)
    Attribute在运行期赋值?
    整几个题给大家玩玩,看看“下盘功夫”怎样
    当stringFormat碰上{和}
    一句SQL语句解决倒序数据分页提取
    C#扩展一般用于linq
    字符串转日期类型
    Dispatcher与UI线程交互
    圆形进度条
  • 原文地址:https://www.cnblogs.com/huihao/p/16300310.html
Copyright © 2020-2023  润新知