剑指offer 正则表达式匹配问题

本文深入探讨了正则表达式匹配的复杂问题,通过动态规划思想解析如何处理包含'.'和'*'的正则表达式,实现了字符串与模式的完全匹配。文章详细解释了状态转移方程,提供了一个具体的Java实现案例。

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

请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。

这道题目感觉比较难。一遇到字符串问题就害怕。结合何老师的课本讲解,以及网上的其他资料进行了相应的学习。下面是相关总结。

首先,给定两个字符串,分别是匹配字符串s与模式串p。匹配字符串是全英文字母的,模式串具有一些特殊字符 '.','*'、根据两个特殊字符的效果,可以将匹配问题分成两类,'*'与非'*'类型。

首先当前字符为非*时,直接将s[i]与p[j]比较即可。具体表示为s[i]==p[j]||p[j]=='.'这时,两字符串是始终匹配的。

若当前字符为*时,则需要分类讨论。因为*可以表示出现0次的情况,这时候,只需要判别s[i+1]与p[j+2]的情况.当出现次数不为0时,需要判断s[i+1]与p[j]的关系。

这里参考了大佬的动态规划的思想,设定状态表示矩阵f[i][j],代表s[i...end],p[j...end]是匹配的情况。

状态转移方程表示为:

1.如果p[j+1]!=*;f[i][j]为真,当且仅当s[i]可以和p[j]匹配,且f[i+1][j+1]是真

2.如果p[j+1]=*;则下面情况中只要有一种满足,f[i][j]就是真

      f[i][j+2]是真

      s[i+1]与p[j]匹配,且f[i+1][j]是真。

import java.util.*;
public class Solution {
    public boolean match(char[] str, char[] pattern) {
        int n=str.length;
        int m=pattern.length;
        int f[][]=new int[n+1][m+1];
        for(int i=0;i<=n;i++){
            for(int j=0;j<=m;j++){
                f[i][j]=-1;
            }
        }
        return dp(0,0,f,str,pattern);
    }
    public boolean dp(int x,int y,int f[][],char[]str,char[]pattern) {
        if(f[x][y]!=-1) return f[x][y]>0;
        int n=str.length;
        int m=pattern.length;
        if(y==m){
            if(x==n){
                f[x][y]=1;
            }
            return f[x][y]>0;
        }
        boolean first_match=x<n&&(str[x]==pattern[y]||pattern[y]=='.');
        boolean ans;
        if(y+1<m&&pattern[y+1]=='*'){
            ans=dp(x,y+2,f,str,pattern)||(first_match&&dp(x+1,y,f,str,pattern));
        }else{
            ans=first_match&&dp(x+1,y+1,f,str,pattern);
        }
        if(ans){
            f[x][y]=1;
        }
        return f[x][y]>0;        
    }
}

记录一下,这道题肯定是要2刷3刷的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值