1. 程式人生 > >leetcode 第10題 Regular Expression Matching

leetcode 第10題 Regular Expression Matching

        週末也沒有做leetcode,感覺有點罪惡啊,這個第10題好難啊,涉及到遞迴了,看的我是頭暈眼花啊。我看著看著還是有點收穫的,我發現題目仍然沒有我想象中的那麼的簡單,如果s = 'a b c d e',p = '. * e',這樣匹配出的結果也是正確的,我就很納悶兒啊,' . '是匹配任意一個字元,可是我以為只能匹配一個字元,但是從這個算例上看,當它和' * '在一起時,' . '可以多次匹配不同的字元,這個是我不太明白的地方。。好的吧,這樣也讓我更加的明白了題意。這個題真的是很難啊!!

        有篇博文寫的這個題目的分析挺不錯的,可以讓人看得懂,連結是:leetcode 10 題目分析

。因為這個分析使用Java寫的程式碼,我把它改成了C++版本並在leetcode上通過了測試。回到題目分析中,裡面的表格就是分析的思路和過程,這個表格非常的重要,為了邏輯清楚,先對p做條件判斷,在此基礎上,再對s做條件判斷。


說明:

對於第4個條件:當p的第二個字元不是星號時,如果S不空且(p.charAt(0) == s.charAt(0) 或者 p.charAt(0)==‘ . ’),則進入下一層遞迴繼續比較分別擷取首元素的s和p;否則,返回false。
對於第5個條件:當p的第二個字元是星號時,如果S不空且(p.charAt(0) == s.charAt(0) 或者 p.charAt(0)==‘ . ’),有兩種分支需要分別判斷:


1、某字元+星號不要匹配s的首字元:(因為星號之前的字元可出現可不出現,該情況不配是考慮到後面有必須匹配的。假設當前匹配並截去s的首字元,會導致後續匹配錯誤。) 截去p的前兩個元素(某字元+星號)並進入下一層遞迴,假如返回true,則當前遞迴返回true;假如返回false,進入分支2。
2、某字元+星號要匹配s的首字元:截去s首字元並繼續條件5的判斷。
對於第6個條件:當p的第二個字元是星號時,非【S不空且(p.charAt(0) == s.charAt(0) 或者 p.charAt(0)==‘ . ’)】,截去p的前兩個元素(某字元+星號)並進入下一層遞迴。

        下面是我修改的C++版本的程式碼:

class Solution {
public:
    bool isMatch(string s, string p) {
        if (p.size() == 0) { //對應步驟1
            if(s.size() == 0)
                return true;
            else
                return false;
        }

        if (p.length() == 1 || p[1] != '*') { //對應步驟2,3,4
            if (s.size() == 0 || (p[0] != '.' && p[0] != s[0]))
                return false;
            else
                return isMatch(s.substr(1), p.substr(1));
        }

        while (s.size() != 0 && (s[0] == p[0] || p[0] == '.')) { //對應步驟5,6
            if (isMatch(s, p.substr(2)))
                return true;
            s = s.substr(1);
        }
        return isMatch(s, p.substr(2));
    }
};
        現在這個題我還沒有緩過勁兒來,我得再想想。。。