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,需要确定除最后一个元素外的剩下元素是否匹配,即动态规划。用递归。

不做了。摔!

【my code】

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;
        }
    }

由于参数列表不同,需要改写,改写又老是出问题〒_〒

字符数组'*' == *(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题!怪不得要用一天!!

 

posted on 2015-05-08 16:47  EmmaLi  阅读(150)  评论(0编辑  收藏  举报

导航