剑指offer -- 正则表达式匹配

题目:

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

分析:

解答本题,需要将各种情况考虑清楚。

首先,考虑字符串和模式为空。

  1. 字符串和模式均为空,此时匹配成功,返回true
  2. 字符串不为空,模式为空,此时匹配失败,返回false
  3. 字符串为空,模式不为空,此时匹配有可能是成功的,也有可能是失败的(例如:字符串为空,模式为“a”,这种情况匹配就是失败的;而字符串为空,模式为“a*”,这种情况匹配就是成功的)

然后,以模式中第二个字符是否为‘*’进行讨论。(这里的“第二个字符”要理解成模式中当前剩余字符的第二个,下文中的“第一个字符”也要理解成当前剩余字符的第一个)

  • 当模式中第二个字符不是‘*’时:
  1. 如果字符串中第一个字符和模式中第一个字符相互匹配,那么字符串和模式都后移1位,然后匹配剩余的字符。
  2. 如果字符串中第一个字符和模式中第一个字符不匹配,此时匹配失败,直接返回false
  • 当模式中第二个字符是‘*’时:
  1. 如果字符串中第一个字符和模式中第一个字符不匹配,则字符串不动,模式后移2位,继续匹配。
  2. 如果字符串中第一个字符和模式中第一个字符相互匹配,此时有3种情况:
<1> 如果*表示0次,则字符串不动,模式后移2位,继续匹配。
<2> 如果*表示1次,则字符串后移1位,模式后移2位,继续匹配。
<3> 如果*表示>=2次,则字符串后移1位,模式不动,继续匹配。

注意:如何判断两个字符是不是匹配的?

如果字符串中的字符和模式中的字符是相同的,那这两个字符是匹配的。
如果模式中的字符是'.',并且字符串中的字符不是'\0',那这两个字符是匹配的。(如果字符串中的字符是'\0',要两字符匹配,那模式中的'.'要表示'\0',那模式中剩余的字符将失效)

根据以上分析,写出代码如下。

代码

class Solution {
public:
    bool match(char* str, char* pattern)
    {
        if (str == nullptr || pattern == nullptr)
        {
            return false;
        }
        
        return matchCore(str, pattern); 
    }
    
    bool matchCore(char* str, char* pattern)
    {
        if (*str == '\0' && *pattern == '\0')
        {
            return true;
        }
        
        if (*str != '\0' && *pattern == '\0')
        {
            return false;
        }
        
        if (*(pattern + 1) != '*')
        {
            if ((*str == *pattern) || (*pattern == '.' && *str != '\0'))
            {
                return matchCore(str + 1, pattern + 1); 
            }
            else
            {
                return false; 
            }
        }
        
        if (*(pattern + 1) == '*')
        {
            if ((*str == *pattern) || (*pattern == '.' && *str != '\0'))
            {
                return matchCore(str, pattern + 2) || matchCore(str + 1, pattern + 2) || matchCore(str + 1, pattern);
            }
            else
            {
                return matchCore(str, pattern + 2); 
            }
        }
    }
};

代码通过测试。

你可能感兴趣的:(C/C++)