LeetCode 10.正则表达式匹配

博客围绕给定字符串和字符规律字符串的匹配问题展开。介绍了使用动态规划求解的思路,分匹配串最后字符不为 '*' 和为 '*' 两种情况讨论,还提及了特殊情况判断。最后给出代码及注释辅助理解。

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

题目:

给定一个字符串s和一个字符规律字符串p,请实现一个支持*.的字符串匹配,判断该字符规律p能否匹配上字符串s
其中:

  • .可以匹配单个字符
  • *可以匹配任意个前面的字符

思路:

本题需要采用动态规划来做,求出部分解,之后通过部分解得出更大范围的解。
根据提供的信息我们可以知道,"*"前面一定是有字符的,并且每个.*都能匹配任意两个字符。
大体总共分两种情况:

  1. 当前匹配串中最后的字符不为*。那么要么匹配s串中的字符,要么不匹配,没有其他情况:如果匹配上了,那么:dp[i][j] = dp[i - 1][j - 1],只需要看前面同时去掉当前位置s和p中的最后一个字符之后剩下的是否能匹配上,只要前面的都能匹配上,那么整体就能匹配上。否则就为false
  2. 当前匹配串中最后的字符为*,只要*前面的字符能和当前s串中的字符相同,那么能分三种小情况:1.*匹配0个字符,2.匹配一个字符,3.匹配两个以上的字符。也就是:dp[i][j] = dp[i][j - 2] || dp[i - 1][j - 2] || dp[i - 1][j],只要有一个为true,那么该位置就可以匹配上。
  3. 最后还有base case,也就是特殊情况判断以下:1.如果s为空,p为空,那么一定可以匹配,返回true,也就是dp[0][0] = true,2.如果s不为空,p为空,一定不匹配,返回false,3.如果s为空,p不为空,那么要看p中能否有*将前面的字符删去并最后和s匹配

以下为代码+注释,代码结合注释应该更好理解一点:


public boolean isMatch(String s, String p) {
		// 将字符串转换为字符数组遍历
        char[] s1 = s.toCharArray();
        char[] p1 = p.toCharArray();
        boolean[][] dp = new boolean[s1.length + 1][p1.length + 1];
        // 初始值设置为true,也就是同时为空的那种情况
        dp[0][0] = true;
        // base case
        // 1. s1为空,p1为空,一定为true
        // 2. s1不为空,p1为空,一定为false,dp数组默认为false,因此不需要改动
        // 3. s1为空,p1不为空,那么只要p串中最后的*把前面的抹去,也有可能为true
       // 第三种特殊情况,将匹配串p遍历一遍,生成结果
        for(int i = 1; i <= p1.length; i++){
            if(p1[i - 1] == '*')
                dp[0][i] = dp[0][i - 2];
        }

        for(int i = 1; i <= s1.length; i++){
            for(int j = 1; j <= p1.length; j++){
                // 情况一:p1此位置不为*,并且值和s串中能匹配上
                if(s1[i - 1] == p1[j - 1] || p1[j - 1] == '.'){
                    // 那么当前位置的值就等于同时去掉该字符的情况的值
                    dp[i][j] = dp[i - 1][j - 1];
                // 情况二,p1此位置为*,就要分情况讨论,匹配0个,匹配一个,或者匹配两个以上三种情况
                }else if(p1[j - 1] == '*'){
                    // 如果*前面的值和当前s中的字符匹配
                    if(s1[i - 1] == p1[j - 2] || p1[j - 2] == '.'){
                        dp[i][j] = dp[i][j - 2] || dp[i - 1][j - 2] || dp[i - 1][j];
                    }else{
                        // 如果不匹配,那么直接查看前面不带不匹配字符的剩余字符串
                        dp[i][j] = dp[i][j - 2];
                    }
                }        
            }
        }
        // 字符串遍历完,返回最后的结果
        return dp[s1.length][p1.length];
    }

笔者也在不断学习中,如有错误,欢迎指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值