Regular Expression Matching

本文介绍了一种使用动态规划解决正则表达式匹配问题的方法。重点在于如何处理特殊符号‘.’和‘*’,并提供了详细的算法流程及C/C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:实现一个正则表达式匹配的判定函数。.表示匹配任意一个字符,*表示它前面的字符可以有任意多个。
思路:动态规划

dp[i][j]表示字串 s[i...len(s)], p[j...len(p)] 是否可以匹配。

那么状态转移方程如下:

dp[i][j] =

c1. p[j+1] != *. if s[i] == p[j] dp[i][j] = dp[i+1][j+1]

else dp[i][j] = false

c2 p[j+1] == '*' (这个情况下,要扩展 *, dp[i][j] 从拓展的情况下,选择一个是真的结果)

if( s[i] == p[j] || p[j] == '.' && (*s) != 0) 当s[i] 和 p[j] 一样的时候,例如 aba, a*b这个时候,i = 0, j = 0, 自然可以匹配a a

如果p[j] == . 因为他可以匹配任何字符,所以和相等关系有基本一样的方式。

并且每一步匹配都要递增 i 的值,如果有成立的,则返回true,否则到匹配终了,返回通配符匹配完成后的结果。


代码:
#include <stdio.h>


class Solution {
public:
bool isMatch(const char *s, const char *p) {
// Start typing your C/C++ solution below
// DO NOT write int main() function    

if( 0 == *p) return 0 == *s;

if(*(p+1) != '*')
{
if(*p == *s || (*p) == '.' && (*s) != 0)
{
return isMatch(s+1, p+1);
}
return false;
}
else
{
while(*p == *s || ((*p) == '.' && (*s) != 0))
{
if(isMatch(s, p + 2))
{
return true;
}
s++;
}
return isMatch(s, p + 2);

}
}
};
bool isMatch(const char *s, const char *p) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function    
        
        if ( !s || !p )
   return !s&&!p;
   int ns=strlen(s);
   int np=strlen(p);
   vector<vector<bool> > dp(ns+1,vector<bool>(np+1,0));
   dp[0][0]=true;
   for(int i=1;i<=ns;i++)
   {
   if ( s[i-1]=='*' )
   {
   assert(i>=2);
   dp[i][0]=dp[i-2][0];
   }
   }
   for(int j=1;j<=np;j++)
   {
   if ( p[j-1]=='*' )
   {
   assert(j>=2);
   dp[0][j]=dp[0][j-2];
   }
   }
   for(int i=1;i<=ns;i++)
   {
   for(int j=1;j<=np;j++)
   {
   if (s[i-1]=='.'||p[j-1]=='.')
   dp[i][j]=dp[i-1][j-1];
   else if ( s[i-1]=='*')
   dp[i][j]=dp[i-1][j]||dp[i-2][j];
   else if ( p[j-1]=='*')
   dp[i][j]=dp[i][j-1]||dp[i][j-2]||(dp[i-1][j]&&(s[i-1]==p[j-2]||p[j-2]=='.'));
   else
   dp[i][j]=dp[i-1][j-1]&&s[i-1]==p[j-1];
   }
   }
   return dp[ns][np];
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值