我是靠谱客的博主 阳光面包,最近开发中收集的这篇文章主要介绍[LeetCode]Regular Expression Matching、Wildcard Matching,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
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
DP的思想跃然纸上啊,注意分情况讨论即可。
注意下面代码中 当 p[j-1] == '*' 的时候的判断比较烦,有几种情况是为true的,最后那个括号里的判断没有的话是不能AC的,为了解决的情况是比如
aa 要和a*匹配,括号里的意思是既然另一个子串是*,那么判断再多一个*前的那个字符能不能把我也匹配了。
LeetCode的用例还是比较简单,没有两个子串都有*的情况。
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 || !p )
return !s&&!p;
int ns=strlen(s);
int np=strlen(p);
vector<vector<bool> > dp(ns+1,vector<bool>(np+1,0));
dp[0][0]=true;
for(int i=1;i<=ns;i++)
{
if ( s[i-1]=='*' )
{
assert(i>=2);
dp[i][0]=dp[i-2][0];
}
}
for(int j=1;j<=np;j++)
{
if ( p[j-1]=='*' )
{
assert(j>=2);
dp[0][j]=dp[0][j-2];
}
}
for(int i=1;i<=ns;i++)
{
for(int j=1;j<=np;j++)
{
if (s[i-1]=='.'||p[j-1]=='.')
dp[i][j]=dp[i-1][j-1];
else if ( s[i-1]=='*')
dp[i][j]=dp[i-1][j]||dp[i-2][j];
else if ( p[j-1]=='*')
dp[i][j]=dp[i][j-1]||dp[i][j-2]||(dp[i-1][j]&&(s[i-1]==p[j-2]||p[j-2]=='.'));
else
dp[i][j]=dp[i-1][j-1]&&s[i-1]==p[j-1];
}
}
return dp[ns][np];
}
};
Wildcard Matching:
Implement wildcard pattern matching with support for '?'
and '*'
.
'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).
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", "*") ? true
isMatch("aa", "a*") ? true
isMatch("ab", "?*") ? true
isMatch("aab", "c*a*b") ? false
思路是一样的,但是这个要比上一个简单一点。还是注意当 p[j]=='*'的时候。
但是大数据的时候,这回O(n2)的这个算法居然不给过了~ 空间溢出,不知道怎么设的~那就逼俺们写个递归的呗~
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||!p)
return !s&&!p;
int na=strlen(s);
int nb=strlen(p);
vector<vector<char> > dp(na+1,vector<char>(nb+1,0));
dp[0][0]=1;
for(int i=1;i<=na;i++)
if(s[i-1]=='*')
dp[i][0]=dp[i-1][0];
for(int j=1;j<=nb;j++)
if(p[j-1]=='*')
dp[0][j]=dp[0][j-1];
for(int i=1;i<=na;i++)
{
for(int j=1;j<=nb;j++)
{
if (s[i-1]=='?'||p[j-1]=='?')
dp[i][j]=dp[i-1][j-1];
else if(s[i-1]=='*')
dp[i][j]=(dp[i-1][j]||dp[i-1][j-1])?1:0;
else if (p[j-1]=='*')
dp[i][j]=(dp[i][j-1]||dp[i-1][j-1]||dp[i-1][j])?1:0;
else
dp[i][j]=(dp[i-1][j-1]&&s[i-1]==p[j-1])?1:0;
}
}
return dp[na][nb];
}
};
递归方法如下,小数据给过,大数据妥妥TLE。。。
class Solution {
public:
bool isMatch(const char *ss, const char *sp) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if (!s || !p )
return !s&&!p;
else if ( *s=='