AcWing 30 正規表示式匹配

2021-09-12 01:43:43 字數 1696 閱讀 8248

題目描述:

請實現乙個函式用來匹配包括'.''*'的正規表示式。模式中的字元'.'表示任意乙個字元,而'*'表示它前面的字元可以出現任意次(含0次)。在本題中,匹配是指字串的所有字元匹配整個模式。

例如,字串"aaa"與模式"a.a""ab*ac*a"匹配,但是與"aa.a""ab*a"均不匹配。

樣例

輸入:

s="aa"

p="a*"

輸出:true

分析:

本題可用遞迴或者動態規劃解決。

下面介紹遞迴的解法:

與一般字串匹配不同的是,這題多了.和*兩個匹配符;對於.可以匹配任何字元,處理較為簡單,但是對於*處理較為複雜。

為了分類更加簡潔,我們在比較s[a]與p[b]時,不先去比較這二者是否相等,而是去判斷p[b+1]是否為*,不為*的話,直接比較s[a]和p[b],匹配時指標均右移,如果p[b+1]等於*,那麼我們分以下幾種情況:

1.s[a] != p[b],意味著如果*不表示把p[b]出現次數置為0,那麼就不匹配,所以此時我們考慮下一種狀態match(s,p,a,b+2)。

2.s[a] == p[b],此時就是不確定性有限狀態機問題了,我們可以進一步轉化為三種狀態。

第一種:和1一樣,即使當前字元匹配,我們還是讓它出現的次數為0,說不定p後面的字元還會和s當前字元匹配呢,這種情況我們容易忽略,也就是match(s,p,a,b+2)。

第二種:*使得p[b]出現一次,也就是b直接右移兩位進行比較即可。即match(s,p,a+1,b+2)。

第三種:*使得p[b]出現不小於2次,那麼可以遞迴的轉化為子問題,b不變,a右移一位。即match(s,p,a+1,b)。

如何說上面分模擬較難以想到的話,那麼這題的邊界情況同樣需要小心翼翼,稍微出錯便不能ac。

s與p都為空,匹配,但是s為空也可以匹配p不為空,比如p為2*,*可以讓前面字元出現次數變為0。當然,一旦模式串p為空,而s非空,那麼肯定是不匹配的。

從下面**可以看見,邊界情況用了兩條語句,在b剛剛越界時判斷一下a是否也越界了;另外,由於分類時首先考慮的是p[b+1],所以還需要判斷b是否是最後乙個字元,如果是,只有在a也到達最後的字元且匹配整體才匹配。

特別要注意的是,a到達邊界時匹配不一定結束,比如s = "ab", p = "abc*",即使s匹配到了邊界,還需要繼續比對才能夠發現是匹配的,因此在s的指標a到達邊界時,需要判斷b + 1的位置是不是*,是則將b繼續右移兩位,不是則為匹配失敗。

class solution 

bool match(string s,string p,int a,int b)

if(b + 1 == p.size()) return a + 1 == s.size() && (s[a] == p[b] || p[b] == '.');

if(p[b+1] != '*')

if(s[a] != p[b] && p[b] != '.') return match(s,p,a,b+2);

return match(s,p,a,b+2) || match(s,p,a+1,b+2) || match(s,p,a+1,b);

}};

正規表示式 匹配

字串 void abtr quint32 ab 表示乙個正規表示式 template class bidirectionaliterator class allocator std allocator sub match bidirectionaliterator class match resul...

正規表示式匹配

請實現乙個函式用來匹配包括 和 的正規表示式。模式中的字元 表示任意乙個字元,而 表示它前面的字元可以出現任意次 包含0次 在本題中,匹配是指字串的所有字元匹配整個模式。例如,字串 aaa 與模式 a.a 和 ab ac a 匹配,但是與 aa.a 和 ab a 均不匹配 解法 首先要想到用遞迴處理...

正規表示式匹配

請實現乙個函式用來匹配包括 和 的正規表示式。模式中的字元 表示任意乙個字元,而 表示它前面的字元可以出現任意次 包含0次 在本題中,匹配是指字串的所有字元匹配整個模式。例如,字串 aaa 與模式 a.a 和 ab ac a 匹配,但是與 aa.a 和 ab a 均不匹配 class solutio...