# 10. Regular Expression Matching <span class='tag' data-diff='hard'></span> {%hackmd RN5D4nggQRO8wzNqxuvlNw %} ## 題目 Given an input string (`s`) and a pattern (`p`), implement regular expression matching with support for `'.'` and `'*'`. ``` '.' Matches any single character. '*' Matches zero or more of the preceding element. ``` The matching should cover the entire input string (not partial). **Note:** ``` s could be empty and contains only lowercase letters a-z. p could be empty and contains only lowercase letters a-z, and characters like . or *. ``` **Example 1:** ``` Input: s = "aa" p = "a" Output: false Explanation: "a" does not match the entire string "aa". ``` **Example 2:** ``` Input: s = "aa" p = "a*" Output: true Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa". ``` **Example 3:** ``` Input: s = "ab" p = ".*" Output: true Explanation: ".*" means "zero or more (*) of any character (.)". ``` **Example 4:** ``` Input: s = "aab" p = "c*a*b" Output: true Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore, it matches "aab". ``` **Example 5:** ``` Input: s = "mississippi" p = "mis*is*p*." Output: false ``` ## 思路 這題如果用javascript內建的regular expression來做,則三行就解決了XDD ```javascript let re = new RegExp(p), result = re.exec(s) || []; return result[0] == s; ``` 但題目應該是希望我們自己寫出parser。一開始想說把`s`跟`p`都先拆成array,再用迴圈不停地pop出最後一個元素,比較他們是否相同,若不同或是有一方空了則離開迴圈,並檢查他們是否都是空。 ```javascript s = (["<s>"]).concat(s.split("")); p = (["<s>"]).concat(p.split("")); let a, b, flag = false; while((a = flag ? a : p.pop()) != "<s>" && (b = s.pop()) != "<s>"){ if(a == "*"){ a = p.pop(); flag = true; } if(a != b && a != "."){ if(flag){ s.push(b); flag = false; continue; } else { p.push(a); break; } } } ``` 其中`flag`的作用是檢查現在是否遇到`'*'`,若是則會把p再pop出一個元素作為比較的元素,並用該元素連續檢查s中pop出來的字元,直至不同,但這樣會有一個問題,如果遇到如下的測資: ``` s = "aaa" p = "aa*" ``` 則最末的`a*`就會將整個s比對完全,從而造成離開迴圈後`p`還有剩下的元素。