【LeetCode & 剑指offer刷题】字符串题17:19 正则表达式匹配(10. Regular Expression Matching)

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

19 正则表达式匹配(hard,了解即可)

题目描述

请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配
 
分析:
来源:牛客网
    解这题需要把题意仔细研究清楚,反正我试了好多次才明白的。
    首先,考虑特殊情况:
         1>两个字符串都为空,返回true
         2>当第一个字符串不空,而第二个字符串空了,返回false(因为这样,就无法
            匹配成功了,而如果第一个字符串空了,第二个字符串非空,还是可能匹配成
            功的,比如第二个字符串是“a*a*a*a*”,由于‘*’之前的元素可以出现0次,
            所以有可能匹配成功)
 
    之后就开始匹配第一个字符,这里有两种可能:匹配成功或匹配失败。但考虑到pattern
    下一个字符可能是‘*’, 这里我们分两种情况讨论:pattern下一个字符为‘*’或
    不为‘*’:
          1>pattern下一个字符不为‘*’:这种情况比较简单,直接匹配当前字符。如果
            匹配成功,继续匹配下一个;如果匹配失败,直接返回false。注意这里的
            “匹配成功”,除了两个字符相同的情况外,还有一种情况,就是pattern的
            当前字符为‘.’,同时str的当前字符不为‘\0’。
          2>pattern下一个字符为‘*’时,稍微复杂一些,因为‘*’可以代表0个或多个。
            这里把这些情况都考虑到:
               a>当‘*’匹配0个字符时,str当前字符不变,pattern当前字符后移两位,
                跳过这个‘*’符号;
               b>当‘*’匹配1个或多个时,str当前字符移向下一个,pattern当前字符
                不变。(这里匹配1个或多个可以看成一种情况,因为:当匹配一个时,
                由于str移到了下一个字符,而pattern字符不变,就回到了上边的情况a;
                当匹配多于一个字符时,相当于从str的下一个字符继续开始匹配)
    之后再写代码就很简单了
 
class Solution
{
public:
    bool match(char* str, char* pattern)
    {
        if (*str == '\0' && *pattern == '\0')
            return true;
        if (*str != '\0' && *pattern == '\0')
            return false;
        //if the next character in pattern is not '*'
        if (*(pattern+1) != '*')
        {
            if (*str == *pattern || (*str != '\0' && *pattern == '.'))
                return match(str+1, pattern+1);
            else
                return false;
        }
        //if the next character is '*'
        else
        {
            if (*str == *pattern || (*str != '\0' && *pattern == '.'))
                return match(str, pattern+2) || match(str+1, pattern);
            else
                return match(str, pattern+2);
        }
    }
};
 
10. Regular Expression Matching
Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'.
'.' Matches any single character.
'*' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Note:
  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like . or *.
Example 1:
Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".
Example 2:
Input:
s = "aa"
p = "a*"
Output: true
Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
Example 3:
Input:
s = "ab"
p = ".*"
Output: true
Explanation: ".*" means "zero or more (*) of any character (.)".
Example 4:
Input:
s = "aab"
p = "c*a*b"
Output: true
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab".
Example 5:
Input:
s = "mississippi"
p = "mis*is*p*."
Output: false

 
/*
问题:正则表达式匹配
pattern字符串p中,'.'表示可以代表任意字符,'*'表示可以代表前面的字符可以出现任意次(可以是0次)
方法:分类讨论(4种情况)
*/
class Solution
{
public:
    bool isMatch(string s, string p)
    {
        if (p.empty()) return s.empty();//p为空时
        if (p.size() == 1) //p长度为1时
        {
            return (s.size() == 1 && (s[0] == p[0] || p[0] == '.'));
        }
       
       
        if (p[1] != '*')//p中第二个字符不为*时
        {
            if(!s.empty() && (s[0] == p[0] || p[0] == '.'))//若s不为空且首字符匹配,则递归比较之后的字符是否匹配
                return isMatch(s.substr(1), p.substr(1)); //s,p均后移一个位置继续判断
            else
                return false;
        }
        else //p中第二个字符为*时
        {
            if(!s.empty() && (s[0] == p[0] || p[0] == '.'))//若s不为空且首字符匹配, *可以表示0个字符和多个字符的情况
                return isMatch(s, p.substr(2)) || isMatch(s.substr(1), p); //两种情况对应p后移两个位置和s递归后移一个位置(如, s: aab p: a*b)
            else
                return isMatch(s, p.substr(2)); //若s为空或者首字符不匹配,*只能表示0个字符的情况,p后移两个位置进行判断(如, s: aab p: c*a*b)
        }
    }
};
 

 

posted @ 2019-01-05 16:14  wikiwen  阅读(139)  评论(0编辑  收藏  举报