【动态规划】正则表达式
1. 题目
题目列表:
序号 | 题目 | 难度 |
---|---|---|
1 | 10. 正则表达式匹配 | 困难 |
2. 应用
2.1. Leetcode 10. 正则表达式匹配
题目
解题思路
设
显然,当两个字符串的长度都是零时,它们可以匹配成功,因此,边界条件:
通过分析,容易看出来:
-
如果模式串
的某一个位置是一个普通字符(字母或者点号)时,它只能匹配字符串 中的一个字符; -
如果模式串
的某一个位置是一个星号字符时,它可以多次匹配 中的多个相同的字符。
因此,对于
-
当
是字母时:-
如果当前两个字符相等,即
,那么,当前状态可以通过前一个状态转移得到,即 -
如果当前两个字符不相等,即
,那么,两个字符串就不匹配,即
因此,当
是字母时,其状态转移方程为: -
-
当
是*
时,那么,它可以对字符串 匹配任意次:-
如果星号匹配零次,即星号没有匹配到字符串
中的字符,那么,它可以通过前一个状态转移得到 -
如果星号匹配多次,那么,此时有两种情况:
-
当前匹配成功了,即消耗了一个字符串
中的字符 ,当前状态与状态 相同; -
当前匹配结束了,此时,需要去掉模式串
中的 字母 + 星号 组合,当前状态与状态 相同。
上述两种情况,只要有一种情况匹配成功即可。
-
因此,当
是字母时,其状态转移方程为: -
-
当
是.
时,那么,它可以成功匹配字符串 中的任意字符;
综上,状态转移方程为:
其中,.
时,返回 true
。
注意:这里
表示逻辑或, 表示逻辑与。
注意:长度为零的模式串不能匹配任何字符串。
代码实现
class Solution { public boolean isMatch(String s, String p) { int m = s.length(), n = p.length(); boolean[][] dp = new boolean[m + 1][n + 1]; dp[0][0] = true; for (int i = 0; i <= m; i++) { for (int j = 1; j <= n; j++) { if (p.charAt(j - 1) == '*') { dp[i][j] |= dp[i][j - 2]; if (match(s, i, p, j - 1)) { dp[i][j] |= dp[i - 1][j]; } } else { if (match(s, i, p, j)) { dp[i][j] |= dp[i - 1][j - 1]; } } } } return dp[m][n]; } private boolean match(String s, int i, String pattern, int j) { // 判断s[i - 1]与p[j - 1]是否匹配 if (i == 0) { return false; } if (pattern.charAt(j - 1) == '.') { return true; } return s.charAt(i - 1) == pattern.charAt(j - 1); } }
本文作者:LARRY1024
本文链接:https://www.cnblogs.com/larry1024/p/17979801
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步