10.正则表达式匹配

正则表达式匹配

状态转移方程:f[i][j] 表示从s串下标为i之后 与 p串下标为j之后是否匹配

  1. 第一种情况p[j+1]不为'*':字符匹配(包括字符相同和p串此处字符为'.'
    • f[i][j] = f[i + 1][j + 1] && (s[i] == p[j] || p[j] == '.')
  2. 第二种情况p[j+1]'*'
    • (f[i+1][j] && f[i] == f[j]) || f[i][j+2])
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 i, int j, s, p) {
        if (f[i][j] != -1) return f[i][j];
        if (j == m) return f[i][j] = i == n;
        bool match = i < n && (s[i] == p[j] || p[j] == '.');
        bool ans;
        if (j + 1 < m && p[j + 1] != '*')
            ans = dp(i+1, j+1, s, p) && match;
        else {
            ans = dp(i, j + 2, s, p) || (match && dp(i+1, j, s, p));
        }
        return f[i][j] = ans;
    }
};

比较容易理解的方式

状态转移方程f[i][j]表示前s的前i个与p的前j个相匹配

  1. p串第j个位置不为'*'f[i][j] = f[i - 1][j - 1] && s[i] == p[j] || p[j] == '.'
  2. p串第j个位置为'*'
    • 如果'*'在此是让它前面的字符出现零次 则有:f[i][j] = f[i][j-2]
    • 如果是让前面的字符出现多次 则有:f[i - 1][j] && (s[i] == p[j - 1] || p[j - 1] == '.');

代码如下:

bool isMatch(string s, string p) {
    s = " " + s, p = " " + p;
    int n = s.size(), m = p.size();
    vector<vector<bool>> f(n+1, vector<bool>(m+1, false));
    int i = 0, j = 0;
    f[0][0] = true; //两个串都为空,满足条件
    for (int i = 0; i < s.size(); i++) {
        for (int j = 1; j < p.size(); j++) {
            if (j + 1 < p.size() && p[j + 1] == '*') continue; //当前位应该和下一位看作整体;
            if (i && p[j] != '*') {
                f[i][j] = f[i - 1][j - 1] && (s[i] == p[j] || p[j] == '.');
            } else if (p[j] == '*') {
                f[i][j] = f[i][j - 2] || i && f[i - 1][j] && (s[i] == p[j - 1] || p[j - 1] == '.');
            }
        }
    }
}
原文地址:https://www.cnblogs.com/mayapony/p/13033173.html