力扣题目10 正则表达式匹配

10,正则表达式匹配

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.''*' 的正则表达式匹配。

  • '.' 匹配任意单个字符

  • '*' 匹配零个或多个前面的那一个元素

  • '*' 匹配零个或多个前面的那一个元素

所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

示例 1:

输入:s = "aa", p = "a"
输出:false
解释:"a" 无法匹配 "aa" 整个字符串。

示例 2:

输入:s = "aa", p = "a*"
输出:true
解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。

示例 3:

输入:s = "ab", p = ".*"
输出:true
解释:".*" 表示可匹配零个或多个('*')任意字符('.')。

思路分析

该题是用动态规划的思路去完成的。之后会出一篇专门讲解动态规划的文章。

代码实现(建议复制后去idea中观看)

/**
 * @version v1.0
 * @ProjectName: 数据结构
 * @ClassName: Solution10
 * @Description: 请描述该类的功能
 * @Author: 赵先生
 * @Date: 2022/3/4 10:12
 */

public class Solution10 {
    public boolean isMatch(String s, String p) {
        //获取字符串和匹配规则的长度
        int sLen = s.length(), pLen = p.length();
        //创建一个二维数组,填写可能出现的结果
        boolean[][] memory = new boolean[sLen+1][pLen+1];
        //因为如果s和p都为空的,那么他们是匹配的
        memory[0][0] = true;
        for(int i = 0; i <= sLen; i++) {
            //j从1开始是因为在[0][0]处我们已经初始化过了,而当i不为0的时候,j如果为0肯定不匹配,没有讨论的意义。
            for(int j = 1; j <= pLen; j++) {
                //如果p的最后一个字符为*,则需要进行讨论。因为*可以代表一个前字符的任意数
                if(p.charAt(j-1) == '*') {
                    /**
                     * 如果*表示0个数,就说明s的最后一个字符必须要和p倒数第2个字符前要相等 memory[i][j-2]
                     * 如果*表示1个数,就说明除了最后一个字符以外要和p的倒数第2个字符前要相等,且s的最后一个字符和p的倒数第2的
                     *    数相等 memory[i-1][j-2] && s.charAt(i-1) == p.charAt(j - 2)
                     * 如果*表示2个数,就说明除了最后两个个字符以外要和p的倒数第2个字符前要相等,且s的最后一,二个字符和p的倒数第2的数相等
                     *     memory[i-2][j-2] && s.charAt(i-1) == p.charAt(j - 2) && s.charAt(i-2) == p.charAt(j - 2)
                     * ...
                     * 换作表达式为 memory[i][j] = memory[i][j-2] || (memory[i-1][j-2] && s.charAt(i-1) == p.charAt(j - 2)) || (memory[i-2][j-2] && s.charAt(i-1) == p.charAt(j - 2) && s.charAt(i-2) == p.charAt(j - 2)) || ...
                     * 但是为了简化步骤,所以将后两个步骤整合
                     *  memory[i-1][j] = memory[i-1][j-2] || (memory[i-2][j-2] && s.charAt(i-2) == p.charAt(j - 2)) || (memory[i-3][j-2] && s.charAt(i-2) == p.charAt(j - 2) && s.charAt(i-3) == p.charAt(j - 2)) || ...
                     *  这个时候发现memory[i-1][j] 是可以替换掉  (memory[i-1][j-2] && s.charAt(i-1) == p.charAt(j - 2)) || (memory[i-2][j-2] && s.charAt(i-1) == p.charAt(j - 2) && s.charAt(i-2) == p.charAt(j - 2)) || ...
                     *  变为memory[i][j] = memory[i][j-2] || (i > 0 && (s.charAt(i-1) == p.charAt(j-2) || p.charAt(j-2) == '.') && memory[i-1][j])
                     */
                    memory[i][j] = memory[i][j-2] || (i > 0 && (s.charAt(i-1) == p.charAt(j-2) ||
                            p.charAt(j-2) == '.') && memory[i-1][j]);
                }else {
                    //如果p[j]中没有*号,那么必须满足i是大于0的,且这s[i-1]和p[j-1]是相等的或者有何p的最后一个字符为.   前面条件成立
                    //的前提是他们他们memory[i-1][j-1]是成立的。
                    memory[i][j] = i > 0 && (s.charAt(i-1) == p.charAt(j-1) || p.charAt(j-1) == '.')
                            && memory[i-1][j-1];
                }
            }
        }
        return memory[sLen][pLen];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值