字符串-正则表达式匹配-JZ52

这篇博客探讨了一个用于匹配包含'.‘和’‘的正则表达式的函数实现。函数通过递归处理不同情况,如正常字符、点字符和星号字符,以判断字符串是否与模式匹配。文章详细解释了算法思路,包括转移方程和初始条件,并给出了O(MN)时间复杂度和O(MN)空间复杂度的解决方案。

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

输入: “aaa”,“a*a”
返回值: true

思路
假设主串为 str,模式串为 pattern 从最后一步出发,需要关注最后进来的字符。假设 str 的长度为 n ,pattern的长度为 m ,关注正则表达式 pattern的最后一个字符是谁,它有三种可能,正常字符、’*’ 和 ‘.’(点),那针对这三种情况讨论即可,如下:

  1. 如果 pattern的最后一个字符是正常字符,那就是看str[n−1] 是否等于 pattern[m−1],相等则看str [0…n−2]与 pattern [0…m−2],不等则是不能匹配,这就是子问题。
  2. 如果 pattern 的最后一个字符是 ‘.’,它能匹配任意字符,直接看 str [0…n−2]与 pattern [0…m−2]
  3. 如果 pattern 的最后一个字符是‘*’,它代表 pattern[m-2]=c 可以重复0次或多次,它们是一个整体 c*
    情况一:str[n-1] 是 0 个 c,pattern最后两个字符废了,能否匹配取决于 str [0…n−1]和 pattern [0…m−3]是否匹配
    情况二:str[n-1] 是多个 c 中的最后一个(这种情况必须 str[n-1]=c 或者 c=’.’),所以str 匹配完往前挪一个,pattern 继续匹配,因为可以匹配多个,继续看str[0…n−2]和 pattern[0…m−1]是否匹配。

转移方程
f[i][j] 代表 str 的前 i 个和 pattern 的前 j 个能否匹配
对于前面两个情况,可以合并成一种情况 f[i][j]=f[i−1][j−1]
对于第三种情况,对于 c* 分为看和不看两种情况
不看:直接砍掉正则串pattern 的后面两个, f[i][j]=f[i][j−2]
看:正则串pattern 不动,主串str前移一个进行对比,相等则f[i][j]=f[i−1][j]

初始条件
特判:需要考虑空串空正则
空串和空正则是匹配的,f[0][0]=true
空串和非空正则,不能直接定义 true 和 false,必须要计算出来。(比如str= ‘’ ‘’ ,pattern=“a*b*c*”)
非空串和空正则必不匹配,f[1][0]=…=f[n][0]=false
非空串和非空正则,那肯定是需要计算的了。
大体上可以分为空正则和非空正则两种,空正则也是比较好处理的,对非空正则我们肯定需要计算,非空正则的三种情况,前面两种可以合并到一起讨论,第三种情况是单独一种,那么也就是分为当前位置是 ‘*’ (星)和 非’*’ 两种情况了。
结果
开数组要开 n+1 ,这样对于空串的处理十分方便。结果就是 f[n][m]

时间复杂度O(MN):其中 m 和n 分别是字符串 str 和 pattern 的长度,递归全部遍历
空间复杂度O(MN) 二维数组

代码

import java.util.*;


public class Solution {
    public boolean match (String str, String pattern) {
        if (str.length() == 0 && pattern.length() == 0) {
            return true;
        }
        return matchCore(str, pattern);
        
    }
    public boolean matchCore(String str, String pattern) {
        int s = str.length();
        int p = pattern.length();
        //00 用于存放两个空字符串的结果 dp[i][j] 表示模式串前j个是否与字符串前i个匹配
        boolean[][] res = new boolean[s+1][p+1];
        for (int i=0; i<=s; i++) {
            for (int j=0; j<=p; j++) {
                //分成空正则和非空正则两种
                if (j == 0) {
                    //只有字符串和正则串都为空的时候才匹配 返回true
                    //当正则串为空,字符串不为空则 返回false
                    res[i][j] = i == 0 ? true : false;
                } else {
                    //非空正则分为两种情况 * 和 非* 
                    //j-1和i-1是因为数组的第1位代表字符串第0位,依次类推
                    if (pattern.charAt(j-1) != '*') {
                        if (i>0 && (str.charAt(i-1)==pattern.charAt(j-1)
                                 || pattern.charAt(j-1)=='.')){
                            //对应位置相等 或者 正则串对应位置为.
                            res[i][j] = res[i-1][j-1];
                        }
                     } else {
                        //如果第j个是* 那么分两种情况,有一种成立即可
                        //case 1 可以直接忽略*前模式的那个元素(*代表出现0次 比如a* 这两个元素做空字符串)
                        //那么dp[i][j]==true 只需满足 dp[i][j-2]==true即可
                        if(j >= 2){
                            res[i][j] = res[i][j-2];
                        }
                        //case 2 如果dp[i][j-2]不等于true那么要满足第j-1个字符(这个字符也可以为‘.’)与第i个字符匹配即可
                        //下标多减1是因为数组是从1开始记录的
                        if(i>0 && j>=2 && (str.charAt(i-1)==pattern.charAt(j-2)
                               || pattern.charAt(j-2)=='.')){
                            //两个case 有一种符合就行
                            res[i][j] = (res[i][j] || res[i-1][j]);
                        }
                    }
                }
            }
        }
        return res[s][p];
    }
    
}
【激光质量检测】利用丝杆与步进电机的组合装置带动光源的移动,完成对光源使用切片法测量其光束质量的目的研究(Matlab代码实现)内容概要:本文研究了利用丝杆与步进电机的组合装置带动光源移动,结合切片法实现对激光光源光束质量的精确测量方法,并提供了基于Matlab的代码实现方案。该系统通过机械装置精确控制光源位置,采集不同截面的光强分布数据,进而分析光束的聚焦特性、发散角、光斑尺寸等关键质量参数,适用于高精度光学检测场景。研究重点在于硬件控制与图像处理算法的协同设计,实现了自动化、高重复性的光束质量评估流程。; 适合人群:具备一定光学基础知识和Matlab编程能力的科研人员或工程技术人员,尤其适合从事激光应用、光电检测、精密仪器开发等相关领域的研究生及研发工程师。; 使用场景及目标:①实现对连续或脉冲激光器输出光束的质量评估;②为激光加工、医疗激光、通信激光等应用场景提供可靠的光束分析手段;③通过Matlab仿真与实际控制对接,验证切片法测量方案的有效性与精度。; 阅读建议:建议读者结合机械控制原理与光学测量理论同步理解文档内容,重点关注步进电机控制逻辑与切片数据处理算法的衔接部分,实际应用时需校准装置并优化采样间距以提高测量精度。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值