題目描述:
請實現乙個函式用來匹配包括'.'
和'*'
的正規表示式。模式中的字元'.'
表示任意乙個字元,而'*'
表示它前面的字元可以出現任意次(含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...