【算法题】正则表达式匹配
给定通配符*表达的意思是匹配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];
}