给定通配符*表达的意思是匹配0个或多个任意字符。
如abc* 匹配的字符串为以abc开头的任意字符串..
实现函数
bool match(char* p,char*s)其中p为模式串(含*)s为匹配串,按照题意判断二者是否匹配,如果匹配返回true,不匹配返回false
思路:
1。 递归,枚举*代表的字符数目,从0到n,然后用递归解决:
bool
match(
char
*
src,
char
*
dst )
{
while ( * src != ' \0 ' && * src == * dst ) src ++ , dst ++ ;
if ( * src == ' \0 ' && * dst == ' \0 ' ) return true ;
if ( * dst == ' * ' )
{
for ( ; * src != ' \0 ' ; src ++ )
if ( match( src + 1 , dst + 1 ) )
return true ;
}
return false ;
}
{
while ( * src != ' \0 ' && * src == * dst ) src ++ , dst ++ ;
if ( * src == ' \0 ' && * dst == ' \0 ' ) return true ;
if ( * dst == ' * ' )
{
for ( ; * src != ' \0 ' ; src ++ )
if ( match( src + 1 , dst + 1 ) )
return true ;
}
return false ;
}
递归解的实现比较直观,但是复杂度比较大估计到了n平方到n立方之间了
2。动态规划:
bool
is_match(
char
*
p,
char
*
s)
{
bool m[ 128 ][ 128 ];
memset(m, 0 , sizeof (m));
m[ 0 ][ 0 ] = true ;
int pl = strlen(p);
int sl = strlen(s);
if (pl > sl)
{
return false ;
}
for ( int i = 1 ;i <= sl;i ++ )
{
for ( int j = 1 ;j <= pl;j ++ )
{
if (p[j - 1 ] == ' * ' )
{
bool mac = false ;
for ( int k = i - 1 ;k >= 0 ;k -- )
{
mac = mac || m[k][j - 1 ];
if (mac)
{
break ;
}
}
m[i][j] = mac;
}
else
{
m[i][j] = m[i - 1 ][j - 1 ] && (p[j - 1 ] == s[i - 1 ]);
// cout<<i<<j<<m[i-1][j-1]<<m[i][j]<<(p[j]==s[i])<<endl;
}
}
}
return m[sl][pl];
}
{
bool m[ 128 ][ 128 ];
memset(m, 0 , sizeof (m));
m[ 0 ][ 0 ] = true ;
int pl = strlen(p);
int sl = strlen(s);
if (pl > sl)
{
return false ;
}
for ( int i = 1 ;i <= sl;i ++ )
{
for ( int j = 1 ;j <= pl;j ++ )
{
if (p[j - 1 ] == ' * ' )
{
bool mac = false ;
for ( int k = i - 1 ;k >= 0 ;k -- )
{
mac = mac || m[k][j - 1 ];
if (mac)
{
break ;
}
}
m[i][j] = mac;
}
else
{
m[i][j] = m[i - 1 ][j - 1 ] && (p[j - 1 ] == s[i - 1 ]);
// cout<<i<<j<<m[i-1][j-1]<<m[i][j]<<(p[j]==s[i])<<endl;
}
}
}
return m[sl][pl];
}
动态规划的递归式为
1.如果p[j] !=‘*’那么 m[i][j] = m[i-1][j-1]&&(p[j-1]==s[i-1]);
2。如果p[j]=='*' 那么 m[i][j] = m[k][j-1]||m[k-1][j-1] 其中k为 1到i-1
动态规划实质上也是枚举*匹配的字符个数。。。复杂度我感觉一样但是动态规划可以求出字串的匹配,同时如果增加空间复杂度记下匹配的最小下标的话,可以达到n方。这就比递归的优了
动态规划:用mat数组记录能够匹配p[i]的最短s下标:即mat[j] = i .有 p[j]和s[i] 匹配,同时 i为最小下标
代码如下:
bool
is_match(
char
*
p,
char
*
s)
{
bool m[ 128 ][ 128 ];
int mat[ 128 ];
mat[ 0 ] = 0 ;
memset(m, 0 , sizeof (mat));
memset(m, 0 , sizeof (m));
m[ 0 ][ 0 ] = true ;
int pl = strlen(p);
int sl = strlen(s);
if (pl > sl)
{
return false ;
}
for ( int i = 1 ;i <= sl;i ++ )
{
for ( int j = 1 ;j <= pl;j ++ )
{
if (p[j - 1 ] == ' * ' )
{
if ((i - 1 ) >= mat[j - 1 ])
{
m[i][j] = true ;
}
else
{
m[i][j] = false ;
}
}
else
{
m[i][j] = m[i - 1 ][j - 1 ] && (p[j - 1 ] == s[i - 1 ]);
// cout<<i<<j<<m[i-1][j-1]<<m[i][j]<<(p[j]==s[i])<<endl;
}
if (m[i][j] && mat[j] > i )
{
mat[j] = i;
}
}
}
return m[sl][pl];
}
{
bool m[ 128 ][ 128 ];
int mat[ 128 ];
mat[ 0 ] = 0 ;
memset(m, 0 , sizeof (mat));
memset(m, 0 , sizeof (m));
m[ 0 ][ 0 ] = true ;
int pl = strlen(p);
int sl = strlen(s);
if (pl > sl)
{
return false ;
}
for ( int i = 1 ;i <= sl;i ++ )
{
for ( int j = 1 ;j <= pl;j ++ )
{
if (p[j - 1 ] == ' * ' )
{
if ((i - 1 ) >= mat[j - 1 ])
{
m[i][j] = true ;
}
else
{
m[i][j] = false ;
}
}
else
{
m[i][j] = m[i - 1 ][j - 1 ] && (p[j - 1 ] == s[i - 1 ]);
// cout<<i<<j<<m[i-1][j-1]<<m[i][j]<<(p[j]==s[i])<<endl;
}
if (m[i][j] && mat[j] > i )
{
mat[j] = i;
}
}
}
return m[sl][pl];
}