OJ練習45——T10 Regular Expression Matching

正則表達式匹配的斷定函數。正則表達式

Some examples:
isMatch(「aa」,」a」) → false
isMatch(「aa」,」aa」) → true
isMatch(「aaa」,」aa」) → false
isMatch(「aa」, 「a*」) → true
isMatch(「aa」, 「.*」) → true
isMatch(「ab」, 「.*」) → true
isMatch(「aab」, 「c*a*b」) → true數組

【思路】函數

想着單純地考慮全部狀況,後來發現幾乎不可能。寫了一上午,終於寫不下去(┙>∧<)┙へ┻┻測試

由於總體是否能返回true,須要肯定除最後一個元素外的剩下元素是否匹配,即動態規劃。用遞歸。spa

不作了。摔!code

【my code】blog

bool isMatch(string s, string p) {
        int i=0,j=0;
    int m=s.size();
    int n=p.size();
    while(i<m&&j<n){
        if(s[i]!=p[j]){
            if(p[j]=='.'){
                if(p[j+1]=='*'){
                    p+='*';
                    p[j+1]='.';
                    n++;
                }
                p[j]=s[i];
                i++;
                j++;
            }
            else if(p[j]=='*'&&i>0&&j>0){
                p[j]=p[j-1];
                n++;
                p+='*';
                if(p[j]!=s[i])
                    return false;                
            }
            else if(p[j+1]=='*')//aab-c*a*b
                j+=2;
            else return false;
        }
        else{
            i++;
            j++;
        }
    }
    if(j<n&&p[n-1]!='*'||i<m) return false;
    return true;
    }

經過300+個測試用例,不能AC。遞歸

【other code】字符串

bool isMatch(const char *s, const char *p) {
        if ('\0' == *p) { 
            return '\0' == *s;
        }
        
        if ('*' == *(p + 1)) {
            while ((*s != '\0') && ((*s == *p) || ('.' == *p))) {
                if (isMatch(s, p + 2)) {
                    return true;
                }
                
                ++s;
            }
            
            return isMatch(s, p + 2);
        }
        else {
            if ((*s != '\0') && ((*s == *p) || ('.' == *p))) {
                return isMatch(s + 1, p + 1);
            }
            
            return false;
        }
    }

因爲參數列表不一樣,須要改寫,改寫又總是出問題〒_〒string

字符數組'*' == *(p + 1)這樣是沒問題的,可是用下標訪問string會有越界問題。

最終改了能運行小的字符串輸入。

bool isMatch(string s, string p) {
    int m=s.size();
    int n=p.size();
    //if(m==0)
        //return n==0;
if(n==0)
    return m==0;
int i=0,j=0; if((j+1<n)&&p[j+1]=='*'){ while((m>0)&&(i<m)&&(s[i]==p[j]||p[j]=='.')){ if(isMatch(s.substr(i,m-i),p.substr(2,n-2))) return true; i++; } return isMatch(s.substr(i,m-i),p.substr(2,n-2)); } else{ if((m>0)&&(i<m)&&(s[i]==p[j]||p[j]=='.')) return isMatch(s.substr(1,m-1),p.substr(1,n-1)); return false; } }

運行結果是這樣:

行百里者半九十……\(╯-╰)/

哭暈在機房。

終於A了。看上面註釋掉的兩行就是bug緣由。

可是看結果——

耗時428ms!!!

不想說話。

得找到更好的辦法。

【other code】——8ms辦法

bool isMatch(string s, string p) {
        int ls = s.length();
        int lp = p.length();
        bool mark[ls+1][lp+1];
        memset(mark,0,sizeof(mark)); 
        mark[0][0] = 1;
        for(int i = 1; i < lp && p[i] == '*'; i+=2){
            mark[0][i+1] = 1;
        }

        for(int i = 1; i <= ls; ++i){
            for(int j = 1; j <= lp; ++j){
                if(p[j-1] == '.' || p[j-1] == s[i -1])
                    mark[i][j] = mark[i-1][j-1];
                else if(j > 1 && p[j-1] == '*')
                    mark[i][j] = mark[i][j-2] || (mark[i-1][j] && (p[j-2] == '.' || s[i-1] == p[j-2]));   // .*
            }
        }
        return mark[ls][lp];
    }

用一個數組記錄動態規劃的結果。

我只能看代碼知道結果是對的,卻不懂原理。

先到這裏吧。中檔的題目真是作不下去。

【後記】

這原來是一道hard題!怪不得要用一天!!

相關文章
相關標籤/搜索