正则表达式匹配

剑指offer

Posted by chl on January 15, 2019

题目描述

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

解法

字符串和模式一个字符一个字符的进行匹配;
当前字符都相等的情况下就移动到下一个字符; 模式中字符为‘.’时,则与所有字符匹配,两个指针都后移一位; 当模式中当前字符的下一个字符为‘*’时,则有以下情况

  • 当前字符匹配:
    • 由于*表示任意个数,所以模式中的指针可以选择后移两位,表示个数1,此时字符串指针后移1位;
    • 模式指针可以选不移动,表示大于1个,此时字符指针后移1位;
    • 模式指针可以直接后移2位,而字符串指针不移动,表示个数为0(字符不匹配时也是这么操作);
  • 当前字符不匹配时:
    • 模式指针后移2位,字符指针不移动;

当下一个字符不是*,并且当前字符不相等时,直接返回false;

本题使用递归会容易和简洁很多; ## 代码

 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(*pattern == *str || (*pattern == '.' && *str!='\0')){
                return matchCore(str+1,pattern+2) ||
                    matchCore(str+1,pattern) ||
                    matchCore(str,pattern+2);
            }else{
                return matchCore(str,pattern+2);
            }
        }
        
        if(*str==*pattern || (*pattern=='.' && *str!='\0')){
            return matchCore(str+1,pattern+1);
        }
        return false;
    }