【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)
        }
    }
};
 

猜你喜欢

转载自www.cnblogs.com/wikiwen/p/10224968.html