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
解法一: 动态规划
dp[i[[j]:表示s的前i个字符与p的前j个字符是否匹配,即s[0,...,i-1]与p[0,...,j-1]是否匹配。
递推表达:当p[j-1]=='*',只要dp[0,..,i][j-1]中任意一个为真即可;
当p[j-1]=='?',只要dp[i-1][j-1]为真即可;
当p[j-1]=='x',只要dp[i-1][j-1]为真且p[j-1]==s[i-1]即可。
bool isMatch(string s, string p) {
int i,j,m=s.size(),n=p.size();
vector<vector<bool>> dp(m+1,vector<bool>(n+1,0));
dp[0][0]=1;
for(i=1;i<=n;i++)
{
dp[0][i]=dp[0][i-1]&&(p[i-1]=='*');
}
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
if(p[j-1]=='*')
{
for(int k=0;k<=i;k++)
{
// dp[i][j]=dp[i][j]|dp[k][j-1];
if(dp[k][j-1]){dp[i][j]=1;break;}
}
}else if(p[j-1]=='?')
{
dp[i][j]=dp[i-1][j-1];
}else
{
dp[i][j]=dp[i-1][j-1]&&(p[j-1]==s[i-1]);
}
}
}
return dp[m][n];
}
解法二:
转载原文在下面
bool isMatch(string s, string p) {
const char* s1=s.c_str();
const char* p1=p.c_str();
const char* star=NULL;//用来标记'*'的位置
const char* ss=s1;//用来记录和匹配相关的信息
while(*s1){
if((*p1=='?')||(*p1==*s1)) {s1++;p1++;continue;}//当两者匹配,指针都往下移
if(*p1=='*'){
star=p1++;//当遇到‘*’时,只p指针往下移
ss=s1;
continue;
}
if(star) {p1=star+1;s1=++ss;continue;}//如果两个都不匹配,但是p的前面有'*'时,ss向下移一位,代表'*'多匹配一个s的字母
//s的指针s1再向下移,指向代匹配的字母
return false;//当没有*,而且不匹配时,返回假
}
while(*p1=='*') p1++;
return !*p1;
}