正則表達式匹配

請實現一個函數用來匹配包括 '.' 和 '*' 的正則表達式。模式中的字符 '.' 表示任意一個字符,而 '*' 表示它前面的字符能夠出現任意次(包含 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;
    }
}
相關文章
相關標籤/搜索