问题描述:
请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。
做这道题之前,我们必须的了解什么是正则表达式,这个地方有不懂的小伙伴可以去查查看看。
我们从问题入手:
题目的意思是,给我们两个字符串,一个是字符串,另一个是模板,要我们写一个函数来检测两个字符串是否是按照题目中的规则匹配。
题目中说: ‘ . ’这个字符可以表示任意一个字符,而 ‘ * ’ 这个字符表示:它前面的字符可以出现很多次,也包括0次,题目中给了两个例子:
字符串“aaa”与模式串“a.a”可以匹配
因为 ‘ . ’ 这个字符也可以代表a,所以它们匹配。
"aaa" 与 “ab*ac*a” 也能匹配
因为 ' * ' 之前的元素可以出现任意次
了解了题意之后,我们再看看怎么解决这个问题;
首先我们考虑特殊情况:
1.如果两个字符串都是空的话,其实它们是匹配的,所以应该返回true。
2.如果字符串为空,模板串不为空的话,有可能也是匹配的。例如:
字符串为空,模板串为 a*,因为题上说,‘ * ’前的字符可以出现任意次,包含0次,那么这样就是匹配的,所以这种情况下,我们还得做判断
3.如果字符串不为空,模板串为空,那么肯定返回false,因为我们根本无法匹配
其实想到这,问题就变得简单了许多,就是看看模板串中下一个字符 是不是 ‘ * ’,如果不是,那就很简单,看看现在所指的两个字符是否一样如果一样,就继续匹配两个字符串的下一个字符就可以了,这里还有特殊情况,就是字符‘ . ’ 的问题,我们把它考虑进去就OK
下来,就要考虑下如果下一个字符是 ‘ * ’ ,题目上说,这个字符表示,前面出现的字符可以出现任意次,而且还包含0次。那这里,就又得分开来讨论一下:
a. 如果‘ * ’前的字符出现了 0 次,那我们所做的就是要跳过这个字符,也就是我们模板串+2,跳过' * ',而字符串不变
b.如果' * '前的字符出现了1次或多次,其实我们把出现1次和出现多次可以当做一种情况来看。如果出现了一次,那么字符串往后走一个,模板串不动,此时,就变成了a那种情况,如果出现了多次,那就相当于字符串一直往后走,而模板串不变,其实也就是从字符串的下一个开始匹配。
class Solution
{
bool match(char* str,char* pattern)
{
//如果两个字符串都为空
if(*str == '\0' && *pattern == '\0')
return true;
//如果字符串不为空,模板串为空
if(*str != '\0' && *pattern == '\0')
return false;
//如果模板串的下一个字符不为 ‘*’
if(*(pattern + 1) != '*'){
//特殊情况处理,如果两个字符相等或字符串没到\0并且模板串现在的字符为‘.’
if(*str == *pattern || (*str != '\0'&&*pattern == '.'))
return match(str+1,pattern+1);
//否则,就不匹配
else
return false;
}
//模板串的下一个字符为‘*’
else{
//如果字符‘*’前的的字符出现了多次
if(*str == *pattern || (*str != '\0'&&*pattern == '.'))
return match(str,pattern+2) || match(str+1,pattern);
//字符‘*’前的字符出现了0次
else
return match(str,pattern+2)
}
}
};