通配符匹配

支持:?匹配单个字母 和 *匹配 0 或多个字母

bool isMatch(string s, string p) {
    // 设dp[i][j]表示s[i..]和p[j..]匹配,则
    //   当s[i]==p[j] || p[j]=='?'时,dp[i][j] = dp[i+1][j+1]
    //   当p[j]=='*'时,dp[i][j] = dp[i][j+1] /*匹配0个*/ || dp[i+1][j] /*匹配1个或多个*/
    //   否则,dp[i][j]=false
    // 初始化,s匹配完、p也匹配完,dp[M][N]=true;或者,s匹配完、p剩下的全是*,dp[M][,..]=true
    const int M = s.size(), N = p.size();
    vector<vector<bool>> dp(M + 1, vector<bool>(N + 1, false));
    dp[M][N] = true;
    for (int j = N - 1; j >= 0 && p[j] == '*'; j--) {
        dp[M][j] = true;
    }

    for (int i = M - 1; i >= 0; i--) {
        for (int j = N - 1; j >= 0; j--) {
            if (s[i] == p[j] || p[j] == '?') dp[i][j] = dp[i+1][j+1];
            else if (p[j] == '*') dp[i][j] = dp[i][j+1] || dp[i+1][j];
            else dp[i][j] = false;
        }
    }
    return dp[0][0];
}

正则表达式匹配

支持:. 匹配任意字母 和 x*匹配 0 或多个 x

bool isMatch(string s, string p) {
    // 设dp[i][j]表示s[i..]和p[j..]匹配,0<=i<=M,0<=j<=N,则
    // matchOne = i<M && (s[i]==p[j] || p[j]=='.')
    // 当p[j+1]=='*'
    //     dp[i][j] = dp[i][j+2] // 匹配0次
    //     dp[i][j] ||= matchOne && dp[i+1][j] // 递归匹配多次
    // 当p[j+1]!='*'
    //     dp[i][j] = matchOne && dp[i+1][j+1]
    // 初始dp[M][N]=true, dp[<M][N]=false

    const int M = s.size(), N = p.size();
    vector<vector<bool>> dp(M + 1, vector<bool>(N + 1, false));
    dp[M][N] = true; // dp[][N]的其他情况为false

    for (int i = M; i >= 0; i--) {
        for (int j = N - 1; j >= 0; j--) {
            bool matchOne = i < M && (s[i] == p[j] || p[j] == '.');
            if (j + 1 < N && p[j+1] == '*') { // look ahead
                dp[i][j] = dp[i][j+2] || (matchOne && dp[i+1][j]);
            } else {
                dp[i][j] = matchOne && dp[i+1][j+1];
            }
        }
    }
    return dp[0][0];
}
// 递归
bool isMatch(string s, string p) {
    return match(s, 0, p, 0);
}

bool match(const string &s, int si, string &p, int pi) {
    const int M = s.size(), N = p.size();
    if (pi == N) return si == M;
    bool matchOne = si < M && (s[si] == p[pi] || p[pi] == '.');
    if (pi + 1 < N && p[pi+1] == '*') {
        return match(s, si, p, pi + 2) || (matchOne && match(s, si + 1, p, pi));
    } else {
        return matchOne && match(s, si + 1, p, pi + 1);
    }
}

模式匹配

bool wordPattern(string pattern, string str) {
    // 把一一对应的pattern中字母和str中单词同时映射到[1..N]
    unordered_map<char, int> p2i;
    unordered_map<string, int> w2i;
    string w;
    istringstream iss(str);
    int i = 0, N = pattern.size();
    while (iss >> w) {
        if (i == N) return false; // str中单词更多
        char p = pattern[i];
        if (p2i[p] != w2i[w]) return false;
        p2i[p] = w2i[w] = ++i;
    }
    return i == N;
}