leetcode10 Regular Expression Matching 使用动态规划DP 代码详解

本文深入探讨了正则表达式匹配算法,特别是如何使用动态规划解决两个字符串的匹配问题,其中涉及'.', '*'等特殊字符的处理。通过实例解析算法逻辑,包括代码实现和关键步骤说明。

题目:

                                    

大致意思是实现一个两个字串的正则匹配,'.'可以代表任何字母,‘*’表示它之前的字母重复0到多次。

例如 a*可以是aaa或者是a或者为空等等。

 

实现代码:

class Solution {
    public boolean isMatch(String s, String p) {
    if (s == null || p == null) {     //s或p为空则无解
        return false;
    }
    boolean[][] dp = new boolean[s.length()+1][p.length()+1];  //java中初始化默认为false
    dp[0][0] = true;
    for (int i = 0; i < p.length(); i++) {   /*为了消除a*这种与空串的匹配,比如s是空,a*或者a*b*都是满足条件的,执行这个循环就可以得到满足条件的情况,并设为true*/
        if (p.charAt(i) == '*' && dp[0][i-1]) {
            dp[0][i+1] = true;
        }
    }
    for (int i = 0 ; i < s.length(); i++) {
        for (int j = 0; j < p.length(); j++) {
            if (p.charAt(j) == '.') {
                dp[i+1][j+1] = dp[i][j];
            }
            if (p.charAt(j) == s.charAt(i)) {
                dp[i+1][j+1] = dp[i][j];
            }
            if (p.charAt(j) == '*') {
                if (p.charAt(j-1) == s.charAt(i) | p.charAt(j-1) == '.') {
                    dp[i+1][j+1] = (dp[i+1][j] || dp[i][j+1] || dp[i+1][j-1]);
                } else {
                    dp[i+1][j+1] =  dp[i+1][j-1];
                }           
            }
        }
    }
    return dp[s.length()][p.length()];
    }
}

主要算法思想:利用动态规划,建立一张表,每一个格代表当前是否可以匹配。其中的逻辑主要如下;

1, If p.charAt(j) == s.charAt(i) :  dp[i][j] = dp[i-1][j-1];
2, If p.charAt(j) == '.' : dp[i][j] = dp[i-1][j-1];
3, If p.charAt(j) == '*': 
               if p.charAt(i-1) == s.charAt(i) or p.charAt(i-1) == '.':
                              dp[i][j] = dp[i-1][j]    //in this case, a* counts as multiple a 
                           or dp[i][j] = dp[i][j-1]   // in this case, a* counts as single a
                           or dp[i][j] = dp[i][j-2]   // in this case, a* counts as empty
               else : dp[i][j] = dp[i][j-2]  //in this case, a* only counts as empty
               

例如这样的一张表(p为a*b, s为aaab):

 

0

a

*

b

0

T

F

T

F

a

F

T

T

F

a

F

F

T

F

a

F

F

T

F

b

F

F

F

T

举例:

[0,0]格表示s和p都为空,这个时候为true;[1,1]表示的含义就是p为a,s为a时是否成立;[1,2]表示p为a*,s为a时是否可以成立。

 

代码解释:

第一个for循环,主要是为了找出类似p为x*或x*y*这样的字串与s空串的匹配。满足这样的条件应该为true。

之后二重循环,就是利用上述的规则,进行填表的过程。

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值