题目:请实现一个函数用来匹配包含.和*的正则表达式。模式中的字符.表示任意一个字符,而*表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa“与模式"a.a"和”ab*ac*a“匹配,但与"aa.a"及”ab*a“均不匹配。
思路:使用递归,每次判断两个字符
1.如果pattern中当前字符下一个字符不为*并且当前的两个字符相等,或者一个字符为.另一个不为空,因为.可以看做任何字符,所以当前两个字符匹配,判断下一个字符
如果pattern中当前字符下一个字符不为*并且当前的两个字符不相等,返回false
2.如果pattern中当前字符下一个字符为*
1)当前的两个字符相等,或者一个字符为.另一个不为空,因为.可以看做任何字符,所以当前两个字符匹配,开始比较(str+1,pattern+2)
如aaa和a*aa,比较第一个字符时,因为第二个字符串中第二个字符为*,所以再判断第一个字符是否相等或者有一个字符是.如果成立,跳过第二个字符串中的*,将第一个字符串中的第二个字符与第二个字符串中的第三个字符开始比较
2)当前的两个字符不相等,可以将*之前的字符看做出现0次,比较(str,pattern+2);
如aaa和ab*ac*a中,因为第二个字符a和b不相等,可以将b*忽略,比较第一个字符串中的第二个字符和第二个字符串中的第4个字符,因为b*被忽略
#include <iostream>
using namespace std;
bool matchCore(char * str,char * pattern)
{
if(*str=='\0'&&*pattern=='\0')
return true;
if(*str!='\0'&&*pattern=='\0')
return false;
//如果当前匹配字符串的下一个字符为*
if(*(pattern+1)=='*')
{
//如果匹配字符串第一个字符和原字符串第一个字符相等或者匹配字符串第一个字符为.而原字符串第一个字符不为空
if(*pattern==*str||(*pattern=='.'&&*str!='\0'))
{
//因为*之前的字符和原字符串的字符对应匹配,所以可以将*看做1,继续向下匹配
return matchCore(str+1,pattern+2);
}
else
{
//忽略patter中的*和它前一个字符
return matchCore(str,pattern+2);
}
}
//如果当前字符相等,或者匹配字符中为.继续向下判断下一个字符
if(*pattern==*str||(*pattern=='.'&&*str!='\0'))
return matchCore(str+1,pattern+1);
return false;
}
bool match(char * str,char * pattern)
{
if(str==NULL||pattern==NULL)
return false;
return matchCore(str,pattern);
}
int main()
{
char * str="aaa";
char * pattern="aa.a";
cout<<match(str,pattern)<<endl;
return 0;
}
代码:
1.先判断当前字符是否为空,两个都为空返回true,一个为空另一个不为空返回false
2.判断当前字符的下一个字符是否为*,如果成立
(1)判断当前字符是否相等或者一个不为空,另一个为. 此时可以把.看做任意一个字符,所以当前字符匹配,并把*当做出现一次,所以继续比较str+1和 pattern+2(跳过*)
(2)如果(1)不成立,说明当前字符不相等,可以让pattern中的*当做出现0次,即pattern中当前不匹配的这个字符出现了0次,继续让str和pattern+2处的字 符比较
3.如果2不成立,直接比较当前字符,如果匹配继续比较str+1和pattern+1