【LeetCode Hot 100 正則表達式匹配】

題目以下:正則表達式

給你一個字符串 s 和一個字符規律 p,請你來實現一個支持 '.' 和 '*' 的正則表達式匹配。spa

'.' 匹配任意單個字符
'*' 匹配零個或多個前面的那一個元素
所謂匹配,是要涵蓋 整個 字符串 s的,而不是部分字符串。code

 
示例 1:blog

輸入:s = "aa" p = "a"
輸出:false
解釋:"a" 沒法匹配 "aa" 整個字符串。
示例 2:ip

輸入:s = "aa" p = "a*"
輸出:true
解釋:由於 '*' 表明能夠匹配零個或多個前面的那一個元素, 在這裏前面的元素就是 'a'。所以,字符串 "aa" 可被視爲 'a' 重複了一次。
示例 3:字符串

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

輸入:s = "aab" p = "c*a*b"
輸出:true
解釋:由於 '*' 表示零個或多個,這裏 'c' 爲 0 個, 'a' 被重複一次。所以能夠匹配字符串 "aab"。
示例 5:class

輸入:s = "mississippi" p = "mis*is*p*."
輸出:false
 di

提示:動態規劃

0 <= s.length <= 20
0 <= p.length <= 30
s 可能爲空,且只包含從 a-z 的小寫字母。
p 可能爲空,且只包含從 a-z 的小寫字母,以及字符 . 和 *。
保證每次出現字符 * 時,前面都匹配到有效的字符

 

初始思路:

剛開始的解題思路想的是挨個對比兩個字符串,而後分三種不一樣的狀況進行處理,分別是:

1)非特殊字符比較

1.1)後爲*號字符,且當前字符相等,這種狀況太複雜了,要挨個枚舉當前字符匹配的次數;

1.2)後不爲*號字符,且當前字符相等,這種狀況直接返回false;

1.3)兩字符不相等,且後續爲*號,則直接忽略當前字符和*號,進行剩餘字符的比較。

2)當前字符爲.:等同於非特殊符號相等的狀況。

3)當前爲*號,這個比較難處理,當時沒想出來,這道題也所以沒作出來。

 

答案思路:答案使用了動態規劃來解題。

和個人分類不一樣,不過有點共通的地方。按照*號來進行分類。

1)當前字符爲*號,此時分爲兩種狀況;

1.1)此*號不起匹配做用。

1.2)當前*號進行一次匹配,同時*號繼續發揮做用。

2)當前字符不爲*號,則按照非特殊字符的狀況直接進行比較便可;

 

代碼以下:

  
  /*進行字符的比較*/
  bool
matchChar(string & s, string & p,int i, int j) { if(i<0) { return false; }
     /*匹配任意字符*/
if(p[j]=='.') { return true; } return s[i]==p[j]; } bool isMatch(string s, string p) { int m=s.size(),n=p.size();
     /*注意這裏須要分開理解,vecDp[i][j]表示的是S的前i個字符與P的前j個字符匹配;後面進行字符匹配時,要注意下標的選擇*/ vector
<vector<int>> vecDp(m+1,vector<int>(n+1)); vecDp[0][0]=1; for(int i=0;i<=m;i++) { for(int j=1;j<=n;j++) {
         /*對應的第一種狀況*/
if(p[j-1]=='*') {
            /*注意這裏是|=運算符*/ vecDp[i][j]
|=vecDp[i][j-2]; if(matchChar(s,p,i-1,j-2)) {
              /*同上,注意這裏是|=運算符*/ vecDp[i][j]
|=vecDp[i-1][j]; } }
          /*對應的第二種狀況*/
else { if(matchChar(s,p,i-1,j-1)) { vecDp[i][j]=vecDp[i-1][j-1]; } } } } return vecDp[m][n]; }
相關文章
相關標籤/搜索