题目描述
请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。
分析:
首先,考虑特殊请况:
- 两个字符串都为空,返回true.
- 当第一个字符串不空,而第二个字符串空了,返回false(因为这样,就无法匹配成功了,而如果第一个字符串空了,第二个字符串非空,还可能匹配成功的。Eg: a*a*a*a*)
正常情况:每次分别在str和pattern中取一个字符进行比较,如果匹配,则匹配下一个字符,否则,返回不匹配。
分析:递归实现
设匹配递归函数 match(str, pattern)。
1. 如果模式匹配字符的下一个字符是‘*’:
如果pttern当前字符和str的当前字符匹配,:有以下三种可能情况
- pttern当前字符能匹配 str 中的 0 个字符:match(str, pattern+2)
- pttern当前字符能匹配 str 中的 1 个字符:match(str+1, pattern+2)
- pttern当前字符能匹配 str 中的 多 个字符:match(str+1, pattern)
如果pttern当前字符和和str的当前字符不匹配:
- pttern当前字符能匹配 str 中的 0 个字符:(str, pattern+2)
2. 如果模式匹配字符的下一个字符不是‘.’:
对于 ‘.’ 的情况比较简单,’.’ 和一个字符匹配 match(str+1, pattern+1)
3. 如果模式匹配字符的下一个字符是正常字符,且 *str == *pattern,
递归下一个字符 :match(str+1, pattern+1)
实现
注:上边这几类情况,再代码实现中,可以进行归类合并,详见下面的代码:
//正则表达式的匹配
//注:空字符串和“.*”是匹配的
bool match(char* str, char* pattern)
{
//特殊情况处理
//如果str和pattern都为NULL, 返回true
if(*str == '\0' && *pattern == '\0')
{
return true;
}
//str不为NULL, pattern为NULL,一定不匹配,返回false.
//注:str为NULL, pattern不为NULL时,可能匹配。 eg: a*a*a*a*
if(*str != '\0' && *pattern == '\0')
{
return false;
}
//递归进行处理(正常情况)
if(*(pattern+1) == '*') //pattern可匹配0次,1次或多次
{
if(*pattern == *str || (*str != '\0' && *pattern == '.'))
{
return match(str,pattern+2) //*pattern == *str请况下,匹配0个
|| match(str+1,pattern); //匹配多个
}
else //*pattern != *str请况下匹配0次,pattern+2
{
return match(str,pattern+2);
}
}
//pattern下一个字符为. 或正常字符即(*str == *pattern)
if((*str != '\0' && *pattern == '.') || (*str == *pattern))
{
return match(str+1, pattern+1);
}
return false;
}
总结
在写这道题时,首先理解什么是正则表达式,对“*”和“.”的匹配模式进行理解,然后对各种情况进行分析,归类。再具体写代码实现。
图解