面试题——正则表达式的匹配

今天看到这样一个题,实现字符串的模式匹配,具体题目如下:

请实现一个函数来匹配包括'.'和'*'的正则表达式,其中匹配是指字符串的所有字符匹配整个模式串。具体匹配规则如下:模式串中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。

经过简单的分析,我们可以很容易想到利用递归求解,先匹配字符串中的当前字符,如果匹配成功,则递归匹配下一个字符,否则返回 false。下面看看字符串匹配的具体过程:

为了方便说明,str 表示字符串,pattern 表示模式串

   bool match_core (char *str, char *pattern);

1、首先考虑递归出口:

      当 *str == '\0' && *pattern == '\0' ,即 str 和 pattern 都是空串时,我们说它们是匹配的,返回 true;

      当 *str != '\0' && *pattern == '\0',str 无法完成匹配,返回 false.

      【注意】当 *str =='\0' && *pattern != '\0' 时,是有可能匹配成功的,比如:pattern 为 a*,而 str 为空串时,是可以匹配成功的。因为 ‘*’ 前面的字符 a 可以出现0次。

2、我们可以将匹配过程分为两类:一类是*(pattern + 1) != '*';另一类是*(pattern + 1) == '*',下面基于这两种情况讨论该问题的具体实现:

      *(pattern + 1) != '*' 时,只要 *str 与 *pattern 匹配,两个字符串分别向前移动一步。即:

             若  *str == *pattern, 则 match_core (str + 1, pattern + 1);

             若   *str != '\0' && *pattern == '.',则 match_core (str + 1, pattern + 1);

             若 *str 和 *pattern 不满足上述两个条件,说明 *str 和 *pattern 不匹配,直接返回 false。

     *(pattern + 1) == '*' ,根据 *pattern 与 *str 匹配的个数,可以分为下面几种情况:

             若匹配个数为0,即 *pattern 与 *str 不匹配,则match_core (str, patten + 2);

            若匹配个数为 1 个或多个,我们只需要每次将 str 向前移一步,pattern 保持原来的位置,继续做下一轮匹配,即match_core (str + 1, pattern)。

我们考虑这种情况:str = "aaaaa", pattern = "aa*a",按照题目叙述的匹配原则,str 与 pattern 应该是匹配的,但是按照我们刚才分析的思路走下来,match_core返回的是false,分析明显是由漏洞的,我们再来看看*(pattern + 1) == '*'中匹配个数是多个的情况,我们不仅要考虑 str + 1 与 pattern 的匹配, 还要考虑到 str 与 pattern + 2 的匹配情况,只要这两种情况中的任何一种匹配成功, str 和 pattern 都算是匹配成功。

基于上述分析,给出 C++ 代码如下:

//正则表达式匹配核心部分
bool match_core (char *str, char *pattern)
{
	//*pattern == '\0'的两种情况已经分析完,下面的情况肯定是*pattern != '\0'
	if (*str == '\0' && *pattern == '\0')
	{
		return true;
	}
	if (*str != '\0' && *pattern == '\0')
	{
		return false;
	}

	//下面来分析pattern没有走完的情况
	//分为两种情况:一个是模式串的下一个字符为*;另一种是模式串的下啊一个字符不为*
	if (*(pattern + 1) != '*')   
	{
		if (*str == *pattern || (*str != '\0' && *pattern == '.'))
		{
			return match_core(str + 1, pattern + 1);
		}
		else
		{
			return false;
		}
	}
	else
	{
		if (*str == *pattern || (*str != '\0' && *pattern == '.'))
		{
			return match_core (str, pattern + 2) || match_core (str + 1, pattern);
		}
		else
		{
			return match_core (str, pattern + 2);
		}
	}
}

bool match (char *str, char *pattern)
{
	if (str == NULL && pattern == NULL)
	{
		return true;
	}
	if (str == NULL || pattern == NULL)
	{
		return false;
	}

	return match_core (str, pattern);
}


   

                 

            


猜你喜欢

转载自blog.csdn.net/trajectoryofbird/article/details/80328559