剑指offer 19. 正则表达式匹配

news2024/10/6 12:19:23

文章目录

    • 1. 题目描述
    • 2. 解题思想
    • 3. 设置dp初始值
    • 4.代码实现

1. 题目描述

在这里插入图片描述

2. 解题思想

  • 定义dp数组

dp[i][j]:表示当字符串长度i,j是,s与p是否匹配

  • 确定递推公式
    核心是s[i]要与p[j]进行比较,比较的结果来确定 dp数组的值,分为下面几种情况:
    (1) 当p[j]是普通字符,直接与s[i]比较,比较的结果就是dp[i][j]的值,这种情况还是比较简单

d p [ i ] [ j ] = { d p [ i ] [ j ] = = d p [ i − 1 ] [ j − 1 ] s [ i ] = = s [ j ] f a l s e s [ i ] ! = s [ j ] dp[i][j]=\begin{cases} dp[i][j]==dp[i-1][j-1]& s[i]==s[j]\\ false & s[i] !=s[j] \end{cases} dp[i][j]={dp[i][j]==dp[i1][j1]falses[i]==s[j]s[i]!=s[j]

如下图dp[i][j]的值取决于,s串的i前面的字符串是否于p串的前j个字符匹配(也就是dp[i-1][j-1]),如果s串的i位置于j的p位置的串不匹配,则一定不匹配
在这里插入图片描述

(2)如果p[j].,则这种情况和第一种情况类似,只是肯定是配置的,不用考虑false的情况,这种情况也很简单
(3)如果p[j]*,这种情况就比较复杂了,由于*的特性,我们需要考虑*前面的字符

如果s[i]*前面一个字符匹配,即s[i]p[j-1]相同,此时*号才生效,此时*匹配了一个a,如果s[i]p[j-1]不相同,则此时*失效,它没有代替任何字符,即表示0个字符(此时*和前面的字符都失效)。下面先分析相同的情况,如下图所示:

在这里插入图片描述

s[i]s[j]相同,此时**可能会和s[i]后面多个与p[j-1]相同的字符匹配,即它可能代表0-n个字符,因为*的匹配个数可能是任意的,考虑下面的情况,此时*只能代表一个字符a。所以我们此时又可以分为三种情况:

在这里插入图片描述

  1. *匹配0个字符,这种情况下,*和前面的字符都失效,如下图的情况,虽然s[i]s[j-1]**前面的字符都是失效的,此时dp[i][j]=dp[i][j-2]
    在这里插入图片描述
  2. *匹配一个字符时,如下图,*代表一个a,此时dp[i][j]=dp[i][j-1]
    在这里插入图片描述
  3. *匹配多个字符时,如下图,*代表5个a,此时s可以不考虑i后面的a了(相当于i后面所有的a与*抵消了),所以变成了下一张图的情况(虚线表示抵消掉了),此时dp[i][j]=dp[i-1][j]
    在这里插入图片描述
    在这里插入图片描述
    所以我们到底需要匹配0个、1个还是多个,具体选择是根据我们选择能够使整个字符串和正则表达式匹配成功。

前面分析了s[i]==p[j-1]的情况,下面分析一下不等于的情况,其实很简单,不相等相当于**前面的字符失效了,不参与匹配了而已,此时s[i]还是可以和p[j-2]进行比较的,关键是要认识到字符+*是可有可无的;

在这里插入图片描述

3. 设置dp初始值

因为存在i-1,所以我们的i一定是从1开始的,所以我们要找出dp[0][j]的所有值(这些值不会在遍历种出现

  • dp[0][0]=true:两个字符串都为空,自动匹配成功
  • dp[0][1]=false: s为空,p的长度为1,肯定为false
  • d p [ 0 ] [ j ] ( j > = 2 ) = { d p [ 0 ] [ j ] = = d p [ 0 ] [ j − 2 ] p [ j ] = = ∗ f a l s e p [ j ] ! = ∗ dp[0][j](j>=2)=\begin{cases} dp[0][j]==dp[0][j-2]& p[j]==*\\ false & p[j] !=* \end{cases} dp[0][j](j>=2)={dp[0][j]==dp[0][j2]falsep[j]==p[j]!=

4.代码实现

class Solution{
  public boolean isMatch(String s, String p){
      //防止空指针,其实根据题目给的参数范围这部分是不需要的
	  if(s==null || p==null){
	     return  true;
	  }
	  //获得两个字符串的长度
	  int n=s.length();
	  int m=p.length();
	  //创建dp数组
	  boolean[][] dp=new boolean[n+1][m+1]
	  //下面按照上面介绍的逻辑,初始化dp数组
	  //两个长度为0的部分默认为true
	  dp[0][0]=true;
	  dp[0][1]=false;
	  for(int j=2;j<=m;j++){
	    //dp[j-1]为*
	  	if(p.charAt(j-1)=='*'){
	  		dp[0][j]=dp[0][j-2];
	  	}
	  }
	  //重点部分
	  for(int i=1;i <=n ;i++){
	  //j初始为1不用担心越界(后面存在j-2的情况)是因为*不可能出现在第一个位置
	    for(int j=1;j<=m;j++){
			//当p[j]不为*
			if(p.charAt(j-1) !='*){
			     //当s[i]与s[j]相等或s[j]为.,则匹配成功
				if(p.charAt(j-1) == '.'|| s.charAt[i]==p.charAt[j])
				{
					dp[i][j]=dp[i-1][j-1];
				}
				else{
					dp[i][j]=false;
				}
			}
			//当p[j]为*时
			else{
			//当s[i]不等于你p[j-1]时(即s[i]和*前的字符不匹配)
				if(p.charAt[j-2] !=s.charAt[i] && p.charAt[j-2]!='.')
				{
				//此时*和*前面的字符失效,相当于从p种踢出,但s[i]还是可以和p[j-2]进行匹配的
					dp[i][j]=dp[i][j-2];
				}else
				{
				// 匹配0个或者1个,或者多个 (下面只有一个情况为true,等于为true的那个即可,所以可以用或连接起来
				dp[i][j]= dp[i][j-2] || dp[i][j-1] || dp[i-2][j];
				}
			}
	    }
	  } 
	  return dp;
 }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/529990.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32-ADC多通道输入实验

之前已经介绍了几个ADC的笔记和实验了&#xff0c;链接如下&#xff1a; 关于ADC的笔记1_Mr_rustylake的博客-CSDN博客 STM32-ADC单通道采集实验_Mr_rustylake的博客-CSDN博客 STM32-单通道ADC采集&#xff08;DMA读取&#xff09;实验_Mr_rustylake的博客-CSDN博客 接下来…

NodeJs基础之NRM与NPM

nrm nrm can help you easy and fast switch between different npm registries, now include: npm, cnpm, taobao, nj(nodejitsu). 译文&#xff1a;nrm可以帮助您在不同的npm注册表之间轻松快速地切换&#xff0c;现在包括&#xff1a;npm、cnpm、taobao、nj&#xff08;no…

编译安装及yum安装

一、编译安装 源码包&#xff1a;是由程序员按照特定格式和语法编写的包 二进制包:源码包经过成功编译之后产生的包 1.tar -xf httpd-2.4.29.tar.bz #解压源码包 2.安装依赖环境 3.配置安装路径 4.编译make并安装 5.关闭防火墙&#xff0c;和安全机制 6.开启服务器 7.…

全电发票时代,记账凭证不用再打印了!

—政策通告— 为进一步推进电子发票应用和推广实施工作&#xff0c;助力国家数字经济发展&#xff0c;国家档案局会同财政部、商务部、国家税务总局总结三批增值税电子发票电子化报销、入账、归档试点经验&#xff0c;依据国家相关法律法规和标准规范&#xff0c;编制形成了《…

KMP匹配算法

目录 一、暴力匹配法动画演示代码实现 二、KMP算法的概念三、KMP算法的应用题目代码实现 一、暴力匹配法 动画演示 时间复杂度为&#xff1a; O ( m ∗ n ) O(m * n) O(m∗n) 代码实现 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std;int…

Revit API:ErrorHandling

前言 本文介绍 Revit 的错误处理机制。 内容 程序员对错误处理的定义和理解 程序的错误处理机制可以分为两种类型&#xff1a;错误返回码和异常捕捉。 错误返回码是指在程序中遇到错误时&#xff0c;通过函数返回值来表明错误的类型和信息。错误返回码可以在程序中被预测和…

分段存储管理方式

目录 一、分段存储管理方式的引入的需求: 1.方便编程 2.信息共享 3.信息保护 4.动态增长 5.动态链接 二、分段系统的基本原理 1.分段 2.段表 3.地址变换机构 4.分页与分段的主要区别 三、信息共享 四、段页式存储管理方式 1.基本原理 2.地址变换过程 分段与分页…

Spring实现IOC和DI入门案例(XML版)

文章目录 1 IOC入门案例(XML版)1.1 思路分析1.2 代码实现步骤1:创建Maven项目步骤2:添加Spring的依赖jar包步骤3:添加案例中需要的类步骤4:添加spring配置文件步骤5:在配置文件中完成bean的配置步骤6:获取IOC容器步骤7:从容器中获取对象进行方法调用步骤8:运行程序 2 DI入门案例…

AltTab for Mac 像Windows一样的窗口快速切换工具

AltTab for Mac AltTab for Mac 是一款非常好用的窗口快速切换工具&#xff0c;AltTab将Windows的 “Alt-Tab” 窗口切换器的功能引入到了macOS。可以让您更快的在各个程序之间自由切换&#xff0c;大大提高您的工作效率。 AltTab for Mac下载 AltTab for Mac AltTab for Ma…

哈工大软件过程与工具作业2

云原生技术云原生技术 哈尔滨工业大学 计算机科学与技术学院/国家示范性软件学院 2022年秋季学期 《软件过程与工具》课程 作业报告 作业 2&#xff1a;需求分析UML建模 姓名 学号 联系方式 石卓凡 120L021011 944613709qq.com/18974330318 目 录 1 需求概述...........…

Vue3——简易版个人空间(上半部分)

创建项目 使用vue 的图形化界面创建一个新的vue3项目如下图所示 装两个新的插件——router和vuex插件 该过程的可能有点久&#xff0c;需要耐心等待。 再装一些需要的依赖 需要用到的依赖: boostrap和poperjs/core&#xff08;bootstrap是提供给不会做美工的程序员的一个新的…

物联网|uart串口相关寄存器|波特率设置及计算|发送处理代码|串口接收中断处理函数|物联网之蓝牙4.0 BLE基础-学习笔记(7)

文章目录 13 uart串口基础开发基本电路图&#xff1a;实验相关寄存器波特率设置及计算计算过程&#xff1a;设置中断发送处理代码串口接收中断处理函数main.c 13 uart串口基础开发 基本电路图&#xff1a; 实验相关寄存器 相关寄存器UxCSR、UxCSR、UxGCR、UxBUF、UxBAUD、CLK…

大厂设计师青睐的十大设计网站

设计绝对是薪酬差距最大的职业之一&#xff0c;有些人年薪100万&#xff0c;有些人月薪3000。 你有没有想过普通人和高薪设计师之间的差距在哪里&#xff1f; 在这篇文章中&#xff0c;我们将解密大厂设计师青睐的十大设计网站。让我们看看&#xff01; 1.即时设计 即时设计…

眺望高阶智能驾驶的远方,北醒驶入新“平台”

从4月到5月&#xff0c;关于2023上海国际车展的话题热度始终不减。 这次车展既让外界感受到了车企们的“卷”&#xff0c;也把智能汽车产业发展的蓝图更加清晰地呈现了出来——智能汽车正在进入产业布局的关键期&#xff0c;产业链上下游发展不断提速。 作为推动汽车产业的“…

基于边缘的图像分割

文章目录 基于边缘的图像分割基本原理常用的算法实现步骤示例代码结论 基于边缘的图像分割 基于边缘的图像分割是数字图像处理中常用的一种方法&#xff0c;它通过检测图像中的边缘信息来实现图像的分割。边缘通常代表着图像中不同区域之间的边界或目标的轮廓&#xff0c;因此…

Java 8 腰斩,Java 17 暴涨 430% (文末惊喜福利)

文末送出惊喜赠书福利一份&#xff0c;绝对high到爆&#xff01; 预约视频号&#xff1a;《Java核心技术》新书发布会暨"Java核心技术大会2023"启动仪式 New Relic 最新发布了一份 “2023 年 Java 生态系统状况报告”&#xff0c;旨在提供有关当今 Java 生态系统状态…

51单片机(十六)AD/DA

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

罗马斗兽场在古罗马时期为什么这么流行,它对罗马有何影响?

在古罗马时期&#xff0c;斗兽场可谓是当时的一大热门娱乐场所。为何斗兽场如此受欢迎&#xff0c;它又如何影响了罗马社会呢&#xff1f; 斗兽场是古罗马人民的一种独特的娱乐形式。无论贵族、平民还是奴隶&#xff0c;他们都喜欢观看这种刺激的竞技。 有人认为&#xff0c;斗…

弹性盒子的属性

display&#xff1a;指定元素使用弹性盒子布局&#xff0c;属性值为 flex 或 inline-flex。 flex-direction&#xff1a;指定弹性盒子主轴的方向&#xff0c;属性值可以是 row&#xff08;默认值&#xff0c;主轴为水平方向&#xff09;、row-reverse&#xff08;主轴为水平方…

第11章:约束

一、数据完整性与约束的分类 1.为什么需要约束constraint SQL以约束方式对表数据进行额外的条件限制。 为了保证数据的完整性&#xff0c;SQL对表数据进行条件限制 ①实体完整性&#xff1a;同一个表&#xff0c;不能存在两条相同无法区分的记录 ②域完整性&#xff1a;年…