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

不多说,正则表达式,以前只是知道用Python或者Java里的这个模块,却没想过咋写,真正上手的时候发现还真不会,想着dp来着。。。后来发现直接dfs就可以了。。。

明天再写。。。


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

代码太丑陋。。。看到有人很精干就写完了。。。自卑。。。


dp版本

dp的思想就是dp(i,j)表示s的前i个字符和p的前j个字符是匹配的,因此:

1.如果s[i]==p[j] 或者p[j]=='.' ,那么dp(i,j) = dp(i-1,j-1)

2.如果s[i]!=p[j]但是p[j]='*',则需要

  2.1 .判断p[j-1]是否等于s[i]或者是‘.’,如果满足条件,则有两个情况可选:

          s[i]与p[j-1]+'*'匹配、 则dp(i,j) = dp(i-1,j)

          s[i]不与p[j-1]+'*'匹配、则dp(i,j) = dp(i,j-2)

        所以dp(i,j) =  dp(i-1,j) || dp(i,j-2)

  2.2. 如果p[j-1]无法和s[i]匹配,则dp(i,j) = dp(i,j-2)

3. 其他情况,dp(i,j) = false


这里为了节省空间,考虑到dp的时候,只需要存储上一行的信息,所以只用两个vector即可,不需要用一个二维数组。

在dp数组的维度上多一维用来表示空,这里初始化vector的时候,要注意dp(0,0)=true,而且要注意初始化其他dp(0,i)的值,如果p的前面一直都是一个字符+‘*’,则空串能和它匹配。

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        int m = strlen(s)+1;
        int n = strlen(p)+1;
        vector<bool> v1,v2;
        for(int i=0;i<n;i++)
            v1.push_back(false);
        v1[0] = true;
        for(int i=1;i<n;i+=2){
            if(p[i]=='*')
                v1[i+1] = true;
            else
                break;
        }
        for(int i=1;i<m;i++){
            v2.push_back(false);
            for(int j=1;j<n;j++){
                if(s[i-1]==p[j-1] || p[j-1]=='.'){
                    v2.push_back(v1[j-1]);
                }else if(p[j-1]=='*'){
                    if(p[j-2]==s[i-1] || p[j-2]=='.'){
                        v2.push_back(v1[j] || v2[j-2]);
                    }else
                        v2.push_back(v2[j-2]);
                }else{
                    v2.push_back(false);
                }
            }
            v1.clear();
            v1.assign(v2.begin(),v2.end());
            v2.clear();
        }
        return v1[n-1];
    }
};

ac

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值