剑指Offer19 正则表达式匹配

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

示例 1:

输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:

输入:
s = "aa"
p = "a*"
输出: true
解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
示例 3:

输入:
s = "ab"
p = ".*"
输出: true
解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。
示例 4:

输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。
示例 5:

输入:
s = "mississippi"
p = "mis*is*p*."
输出: false
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母以及字符 . 和 *,无连续的 '*'。

 

本来采用循环的方式,后来发现没有正确处理a*a匹配aaa这种格式。

 1 class Solution {
 2 public:
 3     bool isMatch(string s, string p) {
 4         int len1=s.size(),len2=p.size();
 5         int i=0,j=0;
 6         bool any=false,prolong=false;
 7         while(i<len1 && j<len2){
 8             any=prolong=false;
 9             if(p[j]=='.')
10                 any=true;
11             if(p[j+1]=='*')
12                 prolong=true;
13             if(!prolong && !any && s[i]!=p[j])
14                 return false;
15             if(prolong){
16                 if(any || s[i]==p[j]){
17                     char tempch=s[i];                
18                     while(++i<len1 && (any || s[i]==tempch));
19                 }
20             }
21             if(!prolong){
22                 i++;
23                 j++;
24             }
25             else{
26                 j+=2;
27             }
28         }
29         if(i!=len1)
30             return false;
31         if(j!=len2){
32             while(j<len2){
33                 if(j+1<len2){
34                     if(p[j+1]!='*')
35                         return false;
36                     j+=2;
37                 }
38                 else{
39                     return false;
40                 }
41             }
42         }
43         return true;
44     }
45 };

 

改用递归解决,难度不是很大,但是考虑全很困难,而且写出来的代码很难看,理解不方便。

 1 class Solution {
 2 public:
 3     bool recursiveMatch(char *s, char *p)
 4     {   
 5         if (*s == '\0' && *p == '\0')
 6             return true;
 7         if (*s != '\0' && *p == '\0')
 8             return false;
 9         bool any = false, prolong = false;
10         if (*p == '.')
11             any = true;
12         if (*(p + 1) == '*')
13             prolong = true;
14         if (!prolong && !any && *s != *p && *s != '\0')
15             return false;
16         if (prolong && *s == '\0')
17             return recursiveMatch(s, p + 2);
18         if (!prolong)
19         {
20             if (*s == '\0')
21                 return false;
22             else
23                 return recursiveMatch(s + 1, p + 1);
24         }
25         int len = 0;
26         char *ptr = s;
27         while ((any || *ptr == *p) && *ptr != '\0')
28         {
29             ptr++;
30             len++;
31         }
32         bool ret = false;
33         for (int i = 0; i <= len; i++)
34         {
35             ret |= recursiveMatch(s + i, p + 2);
36         }
37         return ret;
38     }
39 
40     bool isMatch(string s, string p)
41     {
42         return recursiveMatch(&s[0], &p[0]);
43     }
44     
45 };

 

书上的代码就很清晰,感觉是写之前思考的不清楚,没有简化问题,p126.

posted @ 2020-07-03 17:22  __rookie  阅读(151)  评论(0编辑  收藏  举报