题目描述
请实现一个函数用来匹配包含.
和*
正则表达式。模式中的字符.
表示任意一个字符,而*
表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。
示例
例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但与"aa.a"和"ab*a"均不匹配。
题解
记忆化搜索
我们设计一个函数dfs(i, j)
,表示从s
的第i
个字符开始和p
的第j
个字符开始进行匹配,返回值即是否匹配,那么本题答案就是dfs(0, 0)
。
函数dfs(i, j)
计算过程如下:
m = s.size(), n = p.size()
- 如果
j
到达了p
的末尾且i
到达了s
的末尾,匹配成功。 - 如果
j
的下一个字符是*
- 匹配0个字符,即
dfs(i, j+2)
- 如果
i < m
且s[i]
和p[j]
匹配,匹配1个字符,即dfs(i+1, j)
- 匹配0个字符,即
- 如果
j
的下一个字符不是*
- 如果
i < m
且s[i]
和p[j]
匹配,即dfs(i+1, j+1)
,否则匹配失败
- 如果
bool regular_expression_match(string str, string pending_match_str) {
int m = str.size(), n = pending_match_str.size();
vector<vector<bool>> table(m, vector<bool>(n));
function<bool(int, int)> match = [&](int i, int j) -> bool {
if (j >= n) {
return i == m;
}
if (table[i][j]) {
return table[i][j] == true;
}
bool res = false;
if (j+1 < n && pending_match_str[j+1] == '*') {
if (match(i, j+2) or (i < m && (str[i] == pending_match_str[j] || pending_match_str[j] == '.') &&
match(i+1, j))) {
res = true;
}
} else if (i < m && (str[i] == pending_match_str[j] or pending_match_str[i] == '.') && match(i+1, j+1)) {
res = true;
}
table[i][j] = res;
return res == true;
};
match(0, 0);
}