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