您的位置:首页 > 其它

LeetCode : Wildcard Matching

2014-06-20 02:19 267 查看
From : https://oj.leetcode.com/problems/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


As the problem Regular Expression Matching, for this problem Dynamic Programming can easily be came up with, and I have also used so
much time to try if it is a viable solution of this problem, but I failed. If use DP to solve this problem, maybe you think the space complexity will be O(l_s*l_p), but the trust is not. The useful data for transfer is only in the preceding rows in the array
of DP, so that the space complexity of this code can be O(l_s) or O(l_p). This is the latest try, and I think I cannot optimize this code using DP at present.

class Solution {
public:
bool isMatch(const char *s, const char *p) {
int l=strlen(s),i,j;
bool dp[l+1];
memset(dp,0,sizeof(dp));
dp[0]=true;
for(i=0;p[i];i++)
if(p[i]=='*'){
if(i&&p[i-1]=='*')continue;
for(j=1;j<=l;j++)
dp[j]=dp[j-1];
}
else if(p[i]=='?'){
for(j=l;j--;)
dp[j+1]=dp[j];
dp[0]=false;
}
else{
for(j=l;j--;)
dp[j+1]=(dp[j]&&s[j]==p[i]);
dp[0]=false;
}
return dp[l];
}
};


Meanwhile, if we divide a given string p with '*' into three parts : the part of string before '*' (use A to denote this part), '*' , the part of string after '*' (use B to denote this part). For '*' can match any sequence of
characters, so the number of characters between the part A and B match in string s is no problem. If the place of part A can match is not only one. Let us use a<b<c to replace the end of index part A can match, if part B can match in the interval of [c+1,l_s]
in string s, interval of [a+1,l_s] and [b+1,l_s] are also viable, so just use the leftest viable index match part A can get the right answer.

But just know this cannot accept this problem, for the begin of string s, if the first character is not '*', only the match from the first index is viable. So the end of string s is.

And this is my code, which seem to be crazy, and had Accepted in 168 ms.

class Solution {
public:
bool isMatch(const char *s, const char *p) {
int x=0,y=0;
while(p[0]=='?'||p[0]=='*'){
if(p[0]=='?'){
if(!s[0])return false;
s++;
y++;
}
else x++;
p++;
}
if(!p[0]){
if(x==0)return !s[0];
return true;
}
int flag=-1;
for(int i=0;p[i];i++)
if(p[i]=='*'){
flag=i;
break;
}
if(flag==-1){
if(x==0){
int l=strlen(s);
if(l!=strlen(p))return false;
for(int i=0;i<l;i++)
if(p[i]!='?'&&s[i]!=p[i])return false;
return true;
}
else{
int l1=strlen(s),l2=strlen(p);
if(l1<l2)return false;
for(int i=1;i<=l2;i++)
if(p[l2-i]!='?'&&p[l2-i]!=s[l1-i])return false;
return true;
}
}
int l=strlen(s);
if(l<flag)return false;
if(x==0){
for(int i=0;i<flag;i++)
if(p[i]!='?'&&s[i]!=p[i])return false;
return isMatch(s+flag,p+flag);
}
bool pd;
for(int i=0;i+flag<=l;i++){
pd=true;
for(int j=0;j<flag;j++)
if(p[j]!='?'&&s[i+j]!=p[j]){
pd=false;
break;
}
if(pd)return isMatch(s+i+flag,p+flag);
}
return false;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: