1. 程式人生 > >leetcode 10. Regular Expression Matching 解題報告

leetcode 10. Regular Expression Matching 解題報告

這道題單論難度倒是不難,但是要考慮的方面比較多,因此很容易掉進坑裡去。 題目的大意是模擬正則式匹配,合法的原串輸入是26個小寫字母,匹配正則串的輸入是小寫字母以及’.‘和’*’。 這其中唯一比較麻煩的就是*了,因為它可以有0到原串長度的可能,所以我認為應該用遞迴來做(原來是用for迴圈,但是發現怎麼都處理不好)

  • 首先考慮到正常匹配情況,正常匹配的時候如果沒有*,則一切正常;如果有*,則需要去試探是否存在需要匹配多個字元的情況,因為可能會有這樣的情況,對於aaa,要求匹配aa*aa這類的。
  • 對於失配的情況下,如果存在*,則可以考慮0個的情況,跳過;不然直接返回false。
  • 對於有字串到達邊界的情況,如果匹配正則串到達邊界,則程式必定結束;如果原串到達邊界,則還需要考慮到*
    的問題。比如對於空串來匹配c*c*

此外還需要注意一些細節,一個是記憶體訪問可能超界的情況,我是用巢狀的if來判斷的。還有一個是C中的if和else的配對問題,按照C語言中的定義,else總是和前面未配對的if配對,而不考慮作用域的問題。我沒有驗證C++裡面是否存在這種現象,但還是儘量避免吧。

#include <string>
#include <iostream>
using namespace std;

class Solution {
public:
    bool isMatch(string s, string p) {
        return
recursive(s,p,0,0); } bool recursive(string s,string p,int i,int j) { //cout<<i<<" "<<j<<endl; if(i == s.length() && j == p.length()) { return true; } else if(j>=p.length()) { return false
; } else if(i>=s.length())//consider * { if(j+1<p.length()) { if(p[j+1]=='*'&&j+2<=p.length()) { return recursive(s,p,i,j+2); } } return false; } if(s[i]==p[j] || p[j]=='.') { if(j+1<p.length())//consider * if(p[j+1]=='*') { bool flag = recursive(s,p,i,j+2);//consider 0 characters if(flag) { return flag; } for(unsigned int k = 0;(s[i+k] == p[j] || p[j]=='.')&&i+k<s.length();k++) { flag = recursive(s,p,i+k+1,j+2); if(flag) { return true; } } return false; } return recursive(s,p,i+1,j+1); } else if(s[i]!=p[j] && p[j]!='.')//consider * { if(j+1<p.length()&&p[j+1]=='*') { bool flag = recursive(s,p,i,j+2);//consider 0 characters if(flag) { return flag; } } return false; } } }; int main(void) { Solution s; string a = ""; string b = "c*"; cout<<s.isMatch(a,b)<<endl; return 0; }