剑指offer. 19 正则表达式匹配
题目描述:
请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配
解题思路:
1) dp 看leetcode 题解
2) dfs 剑指offer书上的解法
ab*a 表示b可以出现任意次。
文本串和模式串一个一个位置,如果当前比的位置是i,而模式串i+1位不是*,情况比较简单,匹配上了就双双下一个位置,没对上就false。
但是i+1位是*的话,那就有两种情况了,模式跳过假如这两位置或者不跳过都行。
代码:
// 动规
class Solution {
public:
bool isMatch(string s, string p) {
int len_s = s.size();
int len_p = p.size();
// 初始化 dp 数组, 默认dp[i][0] 初始化为false:对应s非空, p空串的情况
vector<vector<bool>> dp(len_s+1, vector<bool>(len_p+1, false));
dp[0][0] = true;
for (int j=2; j <= len_p; j+=2)
{
dp[0][j] = dp[0][j-2] && (p[j-1] == '*');
}
for (int i = 1; i<=len_s; i++)
{
for (int j = 1; j<=len_p; j++)
{
if (p[j-1] == '*')
{
if (j >= 2)
dp[i][j] = (dp[i-1][j] && (s[i-1] == p[j-2] || p[j-2] == '.')) || dp[i][j-2];
}
else if (p[j-1] == '.')
{
dp[i][j] = dp[i-1][j-1];
}
else
{
dp[i][j] = (s[i-1] == p[j-1]) && dp[i-1][j-1];
}
}
}
return dp[len_s][len_p];
}
};
// dfs
class Solution {
public:
bool match(char* str, char* pattern)
{
//两个特殊情况
if (*str == '\0' && *pattern == '\0') //两个指针都到底了
return true;
if (*str != '\0' && *pattern == '\0') //模式到底了,但是文本没到底,肯定不行
return false;
//假如模式指针下一个不是'*'
if (*(pattern+1) != '*')
{
if (*str == *pattern || (*str != '\0' && *pattern == '.')) //别忘了,'.'代表任意一个字符 也能对上 并且这种情况str不能到底
return match(str+1, pattern+1);
//对上了继续检查
else
return false; //没对上 直接false
}
//假如模式指针下一个是'*'
else
{
//当前对上了的情况
if (*str == *pattern || (*str != '\0' && *pattern == '.'))
return match(str, pattern+2) || match(str+1, pattern);
else
//没对上的情况
return match(str, pattern+2);
}
}
};