目录
10 正则表达式
动态规划题目,找到动态规划的规律
- dp数组含义,dp[i][j]以i-1为结尾的s和以j为结尾的p能否匹配的上
例如dp[5][4]的含义就是s[0..4]和p[0..3]能匹配上 - 初始化
dp[0][0]一定为true不然整个dp数组全是false
如果p形如a*c*b*
因为这里*代表可以出现0次,所以dp[0][2] dp[0][4] dp[0][6]都为true
这样我们得到初始化公式:
//初始化第一行,因为dp[0][2]如果p是a*也是可以匹配上的
for(int j=2;j<=m;j+=2)
{
dp[0][j]=(dp[0][j-2]&&p[j-1]=='*');
}
- 递推公式
这里有点难了
-
p[j-1]!=''
不是的情况比较简单只需要考虑两种情况p[j-1]=='.'
这时无论s[i-1]是什么都能匹配上,dp[i][j]=dp[i-1][j-1]&&p[j-1]=='.'
p[j-1]==s[i-1]
正常匹配dp[i][j]=dp[i-1][j-1]&&p[j-1]==s[i-1]
-
p[j-1]=='*'
这里比较困难p[j-2]
的字符出现了0次,无论p[j-2]是什么都无所谓,所以此时dp[i][j]=dp[i][j-2]
p[j-2]
的字符不是.
而且再出现了所以dp[i][j]= dp[i-1][j]&&s[i-1]==p[j-2]
- 不理解gg
class Solution {
public:
bool isMatch(string s, string p) {
int n=s.length();
int m=p.length();
//dp含义,以i为结尾的s和以j为结尾的p能否匹配
vector<vector<bool>> dp(n+1,vector<bool>(m+1,0));
dp[0][0]=true;
//初始化第一行,因为dp[0][2]如果p是a*也是可以匹配上的
for(int j=2;j<=m;j+=2)
{
dp[0][j]=(dp[0][j-2]&&p[j-1]=='*');
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(p[j-1]=='*')
{
if(dp[i][j-2])
{
dp[i][j]=true;
}
if(dp[i-1][j]&&s[i-1]==p[j-2])
{
dp[i][j]=true;
}
if(dp[i-1][j]&&p[j-2]=='.')
{
dp[i][j]=true;
}
}
else
{
if(dp[i-1][j-1]&&p[j-1]=='.')
{
dp[i][j]=true;
}
else if(dp[i-1][j-1]&&s[i-1]==p[j-1])
{
dp[i][j]=true;
}
}
}
}
for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
cout<<dp[i][j]<<' ';
}
cout<<endl;
}
return dp[n][m];
}
};
标签:10,匹配,结尾,初始化,int,动态,规划,dp
From: https://www.cnblogs.com/liviayu/p/18022611