[leetcode]Regular Expression Matching

题目:

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).

The function prototype should be:
bool isMatch(const char *s, const char *p)

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

解题:

  暴力匹配,只要是要处理"aa","a*a"和"aaa","a*c*a"这两种情况。

bool isMatch(const char *s, const char *p) {   
        bool star = false; 
        char pre;
        const char *str, *ptr;
        for(str = s, ptr =p; *str!='\0'; str++, ptr++)  
        {
            switch(*ptr)  
            {  
                case '.':
                    pre = '.';
                    break;  
                case '*':  
                    if(star == true){
                        star = false;
                        str--;
                    }else{
                        if(*str == pre){
                            int i = 0;
                            s = str; //处理aa,a*a
                            while(*s!='\0'){
                                if(*s++ == pre){
                                    i++;
                                }else{
                                    break;
                                }
                            }
                            str = s-1;
                            p = ptr + 1;
                            if(i > 0 || *p == pre){
                                ptr++;
                            }
                            //处理aa,a*c*a
                            if(*(ptr) != pre){
                                if(*(ptr+1) == '*'){
                                    ptr = ptr+2; 
                                }
                            }
                            star = true;
                        }else if(pre == '.'){
                            star = true;
                        }else{
                            
                            return false;
                        }
                    }
                    break;
                case '\0':
                    return false;
                default:
                {  
                    if(*str != *ptr)  
                    {  
                        star = true;
                        str--;
                    } 
                    pre = *ptr;
                }  
            }  
        }  
        while(*ptr== '*')  
            ptr++;  
        return (*ptr == '\0');
    }

  动态规划:

  dp[i][j]表示字串 s[i...s.size()], p[j...p.size()] 是否可以匹配。

  那么状态转移方程如下:

  dp[i][j] =  dp[i+1][j+1]   (如果p[j+1] != '*' && s[i] == p[j] )

     dp[i][j] = false                 (如果p[j+1] != '*' && s[i] != p[j] )

     如果p[j+1] == '*',这个情况下,要扩展'*', dp[i][j] 从拓展的情况下,选择一个是真的结果。

       如果(s[i] ==  p[j] || p[j] == '.' && (*s) != 0) ,则dp[i][j] = true;

     如果不满足(s[i] ==  p[j] || p[j] == '.' && (*s) != 0) ,则dp[i][j] = dp[i+2][j],也就是每一步匹配都要递增 i 的值,如果有成立的,则返回true,否则到匹配终了,返回通配符匹配完成后的结果。

  解法如下:

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

  

 动态规划的方法参考:http://blog.csdn.net/hopeztm/article/details/7992253

posted @ 2015-02-15 16:23  山楂条子  阅读(197)  评论(0编辑  收藏  举报