正则表达式匹配

请实现一个函数用来匹配包括 '.' 和 '*' 的正则表达式。模式中的字符 '.' 表示任意一个字符,而 '*' 表示它前面的字符能够出现任意次(包含 0 次)。java

在本题中,匹配是指字符串的全部字符匹配整个模式。例如,字符串 "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的下一个字符继续开始匹配)
    以后再写代码就很简单了。
*/

连接:https://www.nowcoder.com/questionTerminal/45327ae22b7b413ea21df13ee7d6429c?f=discussion
来源:牛客网
 函数

当模式中的第二个字符不是“*”时:code

一、若是字符串第一个字符和模式中的第一个字符相匹配,那么字符串和模式都后移一个字符,而后匹配剩余的。字符串

二、若是 字符串第一个字符和模式中的第一个字符相不匹配,直接返回false。get

 

而当模式中的第二个字符是“*”时:io

若是字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配。若是字符串第一个字符跟模式第一个字符匹配,能够有3种匹配方式:class

一、模式后移2字符,至关于x*被忽略;di

二、字符串后移1字符,模式后移2字符;

三、字符串后移1字符,模式不变,即继续匹配字符下一位,由于*能够匹配多位;

 

这里须要注意的是:Java里,要时刻检验数组是否越界。

连接:https://www.nowcoder.com/questionTerminal/45327ae22b7b413ea21df13ee7d6429c?f=discussion
来源:牛客网

public class Solution {
    public boolean match(char[] str, char[] pattern) {
    if (str == null || pattern == null) {
        return false;
    }
    int strIndex = 0;
    int patternIndex = 0;
    return matchCore(str, strIndex, pattern, patternIndex);
}
  
public boolean matchCore(char[] str, int strIndex, char[] pattern, int patternIndex) {
    //有效性检验:str到尾,pattern到尾,匹配成功
    if (strIndex == str.length && patternIndex == pattern.length) {
        return true;
    }
    //pattern先到尾,匹配失败
    if (strIndex != str.length && patternIndex == pattern.length) {
        return false;
    }
    //模式第2个是*,且字符串第1个跟模式第1个匹配,分3种匹配模式;如不匹配,模式后移2位
    if (patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*') {
        if ((strIndex != str.length && pattern[patternIndex] == str[strIndex]) || (pattern[patternIndex] == '.' && strIndex != str.length)) {
            return matchCore(str, strIndex, pattern, patternIndex + 2)//模式后移2,视为x*匹配0个字符
                    || matchCore(str, strIndex + 1, pattern, patternIndex + 2)//视为模式匹配1个字符
                    || matchCore(str, strIndex + 1, pattern, patternIndex);//*匹配1个,再匹配str中的下一个
        } else {
            return matchCore(str, strIndex, pattern, patternIndex + 2);
        }
    }
    //模式第2个不是*,且字符串第1个跟模式第1个匹配,则都后移1位,不然直接返回false
    if ((strIndex != str.length && pattern[patternIndex] == str[strIndex]) || (pattern[patternIndex] == '.' && strIndex != str.length)) {
        return matchCore(str, strIndex + 1, pattern, patternIndex + 1);
    }
    return false;
    }
}
相关文章
相关标签/搜索