LeetCode —— Regular Expression Matching

链接:http://leetcode.com/onlinejudge#question_10

原题:

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

思路:这道题目和Wildcard Matching基本一样,只是测试用例弱很多。

两种方法,DFS和DP。

就讲讲DP吧。

不知道是否有不合法的正则串,不过我都检查了。

状态转移方程:state[strlen(s)+1][strlen(p)+1]

对于s[i], p[j]

1. if p[j] == '.', then state[i+1][j+1] = state[i][j]

2. if p[j] == '*', then

1) if p[j-1] == '.', then state[i+1][j+1] = hasTrue[j-1] (j-1列有true)

2) if p[j-1] == '*', then return false;

3) else, 检查s的最后一段是不是都是一样的元素

3. else

1) if s[i] == p[j], then state[i+1][j+1] = state[i][j], else false

 

代码:

DP

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function    
        int sLen = strlen(s);
        int pLen = strlen(p);
        
        if (pLen > 0 && *p == '*')
            return false;
        
        vector<bool> hasTrue(pLen+1);
        vector<vector<bool> > state(sLen+1, hasTrue);
        
        state[0][0] = hasTrue[0] = true;
        for (int n=1; n<pLen; n+=2) {
            if (p[n] == '*') {
                state[0][n+1] = true;
                hasTrue[n+1] = true;
            } else {
                break;
            }
        }
        
        for (int i=0; i<sLen; i++) {
            for (int j=0; j<pLen; j++) {
                if (p[j] == '.') {
                    state[i+1][j+1] = state[i][j];
                } else if (p[j] == '*') {
                    if (p[j-1] == '*')
                        return false;
                    else if (p[j-1] == '.')
                        state[i+1][j+1] = hasTrue[j-1];
                    else {
                        state[i+1][j+1] = state[i+1][j-1];
                        int n = i;
                        while (n>=0 && s[n] == p[j-1] && !state[i+1][j+1]) {
                            if (state[n][j-1]) {
                                state[i+1][j+1] = true;
                                break;
                            }
                            n--;
                        }
                    }
                } else {
                    if (s[i] == p[j])
                        state[i+1][j+1] = state[i][j];
                    else
                        state[i+1][j+1] = false;
                }
                
                if (state[i+1][j+1])
                    hasTrue[j+1] = true;
            }
        }
        
        return state[sLen][pLen];
    }
};

DFS

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function    
        
		if (s == NULL || p == NULL) {
			if (s == NULL && p == NULL)
				return true;
			else
				return false;
		}

		if (*s == '\0' && *p == '\0')
			return true;
		if (*p == '\0')
			return false;

		if (*(p+1) == '*') {
			int i;
			for (i=0; *(s+i) != '\0'; i++) {
				if (i>0 && *p != '.' && *p != *(s+i-1))
					break;
				if (isMatch(s+i, p+2))
					return true;
			}
			if (*(s+i) == '\0') {
				if (i > 0 && *p != '.' && *p != *(s+i-1))
					return false;
				return isMatch(s+i, p+2);
			}
			return false;
		} else {
			if (*s && (*s == *p || *p == '.'))
				return isMatch(s+1, p+1);
			return false;
		}
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值