剑指offer 18. 正则表达式匹配

简介: 剑指offer 18. 正则表达式匹配

题目描述


请实现一个函数用来匹配包括'.'和'*'的正则表达式。


模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。


在本题中,匹配是指字符串的所有字符匹配整个模式。


例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。


数据范围

输入字符串长度 [0,300]。


样例

输入:
s="aa"
p="a*"
输出:true


题意

字符 . 存在一种情况:

  1. 可以指代任何一个字符。



3bb8d7fc6e3640e19df54a979e366bd9.png


字符 * 存在三种情况:

  1. * 前面的字符出现了 0 次。

  1. * 前面的字符出现了 1


68ea64ea0b094b4b98ec3cdba33f15eb.png

  1. * 前面的字符出现了 n 次。

方法一:动态规划 O(nm)

状态表示: f[i][j] = true 表示 s[i...] 和 p[j...] 相匹配,即 s 从 i 开始以后的字符串与 p 从 j 开始以后的字符串相匹配。


状态转移:


p[j] 是正常字符,f[i][j] = s[i] == p[j] && f[i+1][j+1] 。

如果遇到的是正常的字符,需要判断 s[i] 和 p[j] 是否相等,并且 i 和 j 之后的字符是否都相匹配。

p[j] 是 . ,f[i][j] = f[i+1][j+1] 。

如果遇到了. ,s[i] 和 p[j] 不需要判断是否相等,. 可以指代任何一个字符,所以只用判断 i 和 j 后面的字符是否想匹配即可。

p[j+1] 是 * ,f[i][j] = f[i][j+2] || f[i+1][j] 。

如果遇到了 * ,由于 p[j] 在 s[i] 中出现 0 次或 n 次,所以要分成两种情况判断。第一种是出现 0 次的情况,这时候就需要判断 p[j+2] 是否与 s[i] 相匹配,因为 p[j] 可能在 s[i] 中没有出现;第二种是出现了 n 次的情况, 这时候就要继续取判断 p[j] 是否与 s[i+1] 相匹配。

class Solution {
public:
    vector<vector<int>> f;
    int n, m;
    bool isMatch(string s, string p) {
        n = s.size();
        m = p.size();
        f = vector<vector<int>>(n + 1, vector<int>(m + 1, -1));
        return dp(0, 0, s, p);
    }
    bool dp(int x, int y, string s, string p) {
        if (f[x][y] != -1) return f[x][y]; //判断是否当前状态已经访问过
        if (y == m)
            return f[x][y] = x == n; //判断模式串遍历完后字符串是否也遍历完
        //情况1&&情况2,s[x]与p[y]匹配或p[y]为'.'
        bool first_match = x < n && (s[x] == p[y] || p[y] == '.');
        bool ans;
        //情况3,p[y+1]为'*'
        if (y + 1 < m && p[y + 1] == '*')  //'*'前面字母出现0次||'*'前面字母出现n次
            ans = dp(x, y + 2, s, p) || first_match && dp(x + 1, y, s, p);
        else    //继续向后匹配
            ans = first_match && dp(x + 1, y + 1, s, p);
        return f[x][y] = ans;
    }
};

欢迎大家在评论区交流~

目录
相关文章
|
6月前
|
Java
每日一刷《剑指offer》字符串篇之正则表达式匹配
每日一刷《剑指offer》字符串篇之正则表达式匹配
72 0
每日一刷《剑指offer》字符串篇之正则表达式匹配
|
Java C++
LeetCode(剑指 Offer)- 19. 正则表达式匹配
LeetCode(剑指 Offer)- 19. 正则表达式匹配
105 0
LeetCode(剑指 Offer)- 19. 正则表达式匹配
|
JavaScript
剑指Offer——正则表达式匹配(JS实现)
剑指Offer——正则表达式匹配(JS实现)
165 0
剑指Offer——正则表达式匹配(JS实现)
[剑指offer] 正则表达式匹配
本文首发于我的个人博客:尾尾部落 题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。
1063 0
Python 内置正则表达式库re的使用
正则表达式是记录文本规则的代码,用于查找和处理符合特定规则的字符串。在Python中,常通过原生字符串`r&#39;string&#39;`表示。使用`re.compile()`创建正则对象,便于多次使用。匹配字符串有`match()`(从开头匹配)、`search()`(搜索首个匹配)和`findall()`(找所有匹配)。替换字符串用`sub()`,分割字符串则用`split()`。
|
5月前
|
数据库 Python
Python网络数据抓取(8):正则表达式
Python网络数据抓取(8):正则表达式
57 2
|
5月前
|
自然语言处理 JavaScript 前端开发
Python高级语法与正则表达式(二)
正则表达式描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。
|
5月前
|
安全 算法 Python
Python高级语法与正则表达式(一)
Python提供了 with 语句的写法,既简单又安全。 文件操作的时候使用with语句可以自动调用关闭文件操作,即使出现异常也会自动关闭文件操作。
|
5月前
|
Python
Python使用正则表达式分割字符串
在Python中,你可以使用re模块的split()函数来根据正则表达式分割字符串。这个函数的工作原理类似于Python内置的str.split()方法,但它允许你使用正则表达式作为分隔符。