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