动态规划,关键是处理 * 号, 根据匹配次数进行 状态转移,关键点是 多次匹配时, 保留星号,待匹配字符串划掉当前匹配字符,通过递归,即为多次匹配,不需要手动去写一个循环来处理 多次匹配。仅仅 匹配一次时, 星号去掉,待匹配字符串划掉当前匹配字符。
class Solution {
public:
int width;
bool isMatch(const char * s, const char *p, int * mem, const char * s_src, const char *p_src)
{
if (*s == '\0' && *p == '\0')
{
int rows = (s - s_src);
int cols = (p - p_src);
mem[rows * width + cols] = 1;
return true;
}
if (*p == '\0' && *s != '\0')
{
int rows = (s - s_src);
int cols = (p - p_src);
mem[rows * width + cols] = 0;
return false;
}
int rows = (s - s_src);
int cols = (p - p_src);
if (mem[rows * width + cols] != -1)
{
return mem[rows * width + cols];
}
if (*p != '\0' && *(p + 1) == '*')
{
// 后面是*, 那么尝试匹配
auto res = isMatch(s, p + 1, mem, s_src, p_src);
if (res)
{
int rows = (s - s_src);
int cols = (p+1 - p_src);
mem[rows * width + cols] = 1;
return res;
}
else
{
int rows = (s - s_src);
int cols = (p + 1 - p_src);
mem[rows * width + cols] = 0;
return false;
}
} else if (*p != '*')
{
if (*s != '\0' && (*s == *p || *p == '.'))
{
auto res = isMatch(s + 1, p + 1, mem, s_src, p_src);
int rows = (s + 1 - s_src);
int cols = (p + 1 - p_src);
mem[rows * width + cols] = res;
return res;
}
else
{
int rows = (s - s_src);
int cols = (p - p_src);
mem[rows * width + cols] = 0;
return false;
}
}
else
{
// 先匹配0次, 0次不需要和前面的字符进行比较
auto res = isMatch(s, p + 1, mem, s_src, p_src);
if (res)
{
int rows = (s - s_src);
int cols = (p+1 - p_src);
mem[rows * width + cols] = 1;
return true;
}
else
{
// 尝试匹配 1次或者 多次, 此时需要和前面的字符一致
// 至少 匹配一次的话, s 不能已经到末尾
if ((*s != '\0') && (*s == *(p - 1) || *(p - 1) == '.'))
{
// 尝试匹配多次
auto res = isMatch(s + 1, p, mem, s_src, p_src);
if (res)
{
int rows = (s+1 - s_src);
int cols = (p - p_src);
mem[rows * width + cols] = 1;
return true;
}
else
{
// 尝试只匹配一次,跳过这个*,看后续是否能匹配成功
auto res = isMatch(s + 1, p + 1, mem, s_src, p_src);
if (res)
{
int rows = (s+1 - s_src);
int cols = (p+1 - p_src);
mem[rows * width + cols] = 1;
return true;
}
else
{
int rows = (s+1 - s_src);
int cols = (p+1 - p_src);
mem[rows * width + cols] = 0;
return false;
}
}
}
else
{
int rows = (s - s_src);
int cols = (p - p_src);
mem[rows * width + cols] = 0;
return false;
}
}
}
}
bool isMatch(string s, string p) {
int rows = s.length() + 1;
int cols = p.length() + 1;
int * mem = new int[rows * cols];
memset(mem, 0xff, rows * cols * sizeof(int));
width = p.length();
const char * s_src = s.c_str();
const char * p_src = p.c_str();
return isMatch(s_src, p_src, mem, s_src, p_src);
}
};