剑指Offer52:正则表达式匹配(Java)

参考:
左程云进阶算法第8节视频内容(2小时18分钟处) 视频百度网盘:链接:https://pan.baidu.com/s/1beVfli8bmH9obwNW3NT3Kg 提取码:q5bi
loveforever个人博客网站:https://zhenganwen.top/posts/310d4836/ (有左神算法基础,进阶视频完整笔记代码)

思路分析:

递归版本大概听懂了,动态规划的解法听不懂。看不懂这个题的网上解析的博客不妨看看左神的视频。
递归解法有两个关键点:

  1. 递归解法以函数f(i,j)为基础,str的i,及其后面位置的字符能否和exp的j,及其后面位置上的字符一一匹配,能返回true,不能返回false.然后递归调用本身,判断i+1,j+1的情况。
  2. 因为*很特殊,判断str[i]和exp[j]是否匹配根据*分三种情况:(1).j==exp.length(j,j+1位置都没有字符)。(2).j+1位置有字符但不是*或j有子符j+1没有字符。(3).j+1位置有子符是*。

题目描述

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

java代码:

public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        return match(str,pattern,0,0);
    }

     //这是暴力递归方法
    //这个函数只判断str的i及其之后,与exp的j及其之后是否一一匹配,i,j之前的不管。
    public static boolean match(char[]str,char[]exp,int i,int j){
        //若j没有了字符,则i必须没有字符,否则返回false;
        if(j==exp.length){
            return i==str.length;
        }
        //隐含条件:exp[j]一定是有字符的
        //在j是exp的最后一个字符,或者j后面的字符不是'*'的条件下。exp[j]必须与str[i]匹配,否则返回false
        if(j+1==exp.length||exp[j+1]!='*'){
            return i!=str.length&&(exp[j]==str[i]||exp[j]=='.')&&match(str,exp,i+1,j+1);
        }
        //隐含条件:j后面一定有字符且是'*'
        //在str[i]一定有字符,且str[i]与exp[j]匹配的情况下,通过改变i值判断多种情况是否能够匹配。
        while(i!=str.length&&(exp[j]==str[i]||exp[j]=='.')){
            if(match(str,exp,i,j+2)){
                return true;//只要while循环中有一个匹配成功,即这次的i,j匹配成功
            }
            i++;//通过改变i值,判断了以下情况是否能够匹配:exp[j]匹配了0个str[i],1个str[i],多个str[i]
        }
        return match(str,exp,i,j+2);
    }
}

这个while循环不好理解,loveforever个人博客网站的这个图可以帮助理解

原文地址:https://www.cnblogs.com/dongmm031/p/12359962.html

时间: 2024-12-09 21:53:26

剑指Offer52:正则表达式匹配(Java)的相关文章

剑指OFFER——正则表达式匹配

请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式.例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配 感觉有点难. 分析:递归实现 每次分别在str 和pattern中取一个字符进行匹配,如果匹配,则匹配下一个字符

剑指offer编程题Java实现——面试题7相关题用两个队列实现一个栈

剑指offer面试题7相关题目:用两个队列实现一个栈 解题思路:根据栈的先入后出和队列的先入先出的特点1.在push的时候,把元素向非空的队列内添加2.在pop的时候,把不为空的队列中的size()-1份元素poll出来,添加到另为一个为空的队列中,再把队列中最后的元素poll出来两个队列在栈不为空的情况下始终是有一个为空,另一个不为空的.push添加元素到非空的队列中,pop把非空队列的元素转移到另一个空的队列中,直到剩下最后一个元素,这个元素就是要出栈的元素(最后添加到队列中的元素). 1

剑指offer编程题Java实现——面试题10二进制中1的个数

题目: 请实现一个函数,输入一个整数,输出该整数二进制表示中1的个数.例如,把9表示成二进制是1001,有2位是1,该函数输出2解法:把整数减一和原来的数做与运算,会把该整数二进制表示中的最低位的1变成0,与运算进行多少次就有多少个1. 1 package Solution; 2 /** 3 * 剑指offer面试题10:二进制中1的个数 4 * 题目:请实现一个函数,输入一个整数,输出该整数二进制表示中1的个数. 5 * 例如,把9表示成二进制是1001,有2位是1,该函数输出2 6 * 解法

剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现

用字符串或者数组表示大数是一种很简单有效的表示方式.在打印1到最大的n为数的问题上采用的是使用数组表示大数的方式.在相关题实现任意两个整数的加法.减法.乘法的实现中,采用字符串对大数进行表示,不过在具体的计算中,还是要将字符串转化成字符数组来进行计算. 实现两个大数的加法,要考虑到两个问题,两个数的和的位数问题,以及如何处理两个数按位相加产生的进位问题.首先两个整数相加,两个数的和的位数最多比最大的整数的位数多1:这样和的位数就确定了.对于进位问题,我的做法是先进行按位相加,相加操作完成后再按照

剑指offer编程题Java实现——面试题9斐波那契数列

题目:写一个函数,输入n,求斐波那契数列的第n项. 1 package Solution; 2 3 /** 4 * 剑指offer面试题9:斐波那契数列 5 * 题目:写一个函数,输入n,求斐波那契数列的第n项. 6 * 0, n=1 7 * 斐波那契数列定义如下:f(n)= 1, n=2 8 * f(n-1)+f(n-2), n>2 9 * @author GL 10 * 11 */ 12 public class No9Fibonacci { 13 14 public static void

剑指offer编程题Java实现——面试题14调整数组顺序使奇数位于偶数之前

题目: 输入一个整数数组,实现一个函数来调整该数组中数组的顺序,使得所有的奇数位于数组的前半部分,偶数位于数组的后半部分. 解题思路:数组中维护两个指针,第一个指针初始化时候指向数组头部,第二个指针初始化时候指向数组尾部,第一个指针指向的数字总是偶数,第二个指针指向的数字总是奇数,如果第一个指针在第二个指针之前,则交换两指针指向的元素. 1 package Solution; 2 3 /** 4 * 剑指offer面试题14:调整数组顺序是奇数位于偶数前面 5 * 题目:输入一个整数数组,实现一

《剑指offer》 面试题53 :正则表达式匹配 Java

引言:这道题情况比较复杂,边界条件较多,为了便于以后复习,整理一下.另外,由于C语言和Java对于字符串的操作存在不一样的地方,代码也存在改动. 题目:请实现一个函数用来匹配包含'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次).在本题中,匹配是指字符串的所有字符匹配整个模式.例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"及&quo

剑指offer52:正则表达式匹配

1 题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符‘.’表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式.例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配 2 思路和方法 正则表达式中有三种情况: a.普通字符 b.字符’.’ c.普通字符或’.’ +

剑指Offer-38.平衡二叉树(C++/Java)

题目: 输入一棵二叉树,判断该二叉树是否是平衡二叉树. 分析: 可以从根节点开始遍历每一个节点,求得节点左右子树的最大高度,判断是不是平衡二叉树.这样做的问题在于会重复遍历节点,造成不必要的浪费. 所以可以采用后续遍历来求解此题,判断子树是否是平衡二叉树,如果是,就返回子树的最大高度,不是的话,就中止遍历,这样做的话每个节点只访问一遍. 程序: C++ class Solution { public: bool IsBalanced_Solution(TreeNode* pRoot) { if(