【LeetCode】10.Regular Expression Matching(dp)

【题意】

给两个字符串s和p,判断s是否能用p进行匹配。

【题解】

dp[i][j]表示s的前i个是否能被p的前j个匹配。

首先可以分成3大类情况,我们先从简单的看起:

(1)s[i - 1] = p[j - 1],易得dp[i][j] = dp[i-1][j-1]

(2)p[i - 1] = '.',因为'.'可以匹配任何字符,所以dp[i][j] = dp[i-1][j-1]

(3)p[i - 1] = '*',这种情况就比较复杂了。

当p[j - 2] != s[i - 1] && p[j - 2] != '.'时,即当s = aba,p = abb*这种情况,因为 * 可以代表0个或多个,所以当p[j -2] != s[i - 1]时,往回倒退2个即dp[i][j] = dp[i][j - 2]

然后除去这种情况还有3种匹配情况,只要满足以下任意一种情况也是成立的

当 * 匹配多个时:dp[i][j] = dp[i - 1][j],即当s = abbb,p = ab*,因为b相等所以可以将s最后一个b删去,比较前面的abb与ab*从而实现 * 表示多个

当 * 匹配单个时:dp[i][j] = dp[i][j - 1],即当s = aba,p = aba*

当 * 匹配0个时:dp[i][j] = dp[i][j - 2],上面说过了

【代码】

 1 class Solution {
 2 public:
 3     bool dp[35][35];
 4     bool isMatch(string s, string p) {
 5         s = " " + s;
 6         p = " " + p;
 7         memset(dp , false, sizeof(dp));
 8         dp[0][0] = true;
 9         int m = s.size(), n = p.size();
10         for (int i = 1; i <= m; i++){
11             for (int j = 1; j <= n; j++){
12                 if (s[i - 1] == p[j - 1])dp[i][j] = dp[i - 1][j - 1];
13                 else if (p[j - 1] == '.')dp[i][j] = dp[i - 1][j - 1];
14                 else if (p[j - 1] == '*'){
15                     if (s[i - 1] != p[j - 2] && p[j - 2] != '.')
16                         dp[i][j] = dp[i][j - 2];
17                     else{
18                         dp[i][j] = dp[i][j - 1] || dp[i][j - 2] || dp[i - 1][j];
19                     }
20                 }
21             }
22         }
23         return dp[m][n];
24     }
25 };
View Code
原文地址:https://www.cnblogs.com/z1014601153/p/13829488.html