1. 程式人生 > >10 regular-expression-matching/submissions

10 regular-expression-matching/submissions

這道題其實是一道正則表示式 題目,“.”可以表示任何字母,“*”可以表示對其前面的字母做n次重複,可以看出,最難處理的就是*號,因為按照我們平時的字串匹配演算法,一對一就可以,就算加上“.”也一樣,而給整個演算法加入更多不確定性的就i是“ * ”,換句話說,我們要對“*”的位置進行討論。

“*”只對其前面的一個字母起作用,換句話說,如果一個字串中出現了“*”,假設第k位是*,那麼如果前k-2個字元都匹配了,我們只需要看兩種情況是否符合:

1、s從k-1開始的字串是否和p從k+1開始的字串一樣,即:s.substr(k-1)是否與p.substr(k+1)相等,此時,“*”表示將其前面字元重複0次。

2、s的第k-1位字元和p的第k-1位字元相匹配,此時需要知道 s.substr(k)是否與p.substr(k-1)相等,此時,“*”表示已經將其前面的字元重複了一次,接下去判斷是否需要重複第二次。

以上是兩種特殊情況,第三種情況則是沒有*的情況下,與平時的字串匹配做法類似,一步步往後推進。

3、s的第k-1位字元和p的第k-1位字元相匹配,此時需要對比s.substr(k)是否與p.substr(k)相等。

以下是我學習的大神程式碼,超級精簡,可以說是我見過的最短的leetcode hard程式碼了:

class Solution {
public:
    bool isMatch(string s, string p) {
        if (p.empty()) return s.empty();
        if (p.size() > 1 && p[1]=='*') {
            return isMatch(s, p.substr(2))||(!s.empty()&&(s[0]==p[0] || p[0]=='.')&&isMatch(s.substr(1), p));
        } else {
            return !s.empty()&&(s[0]==p[0] || p[0]=='.')&&isMatch(s.substr(1), p.substr(1));
        }
    }
};