《剑指offer》 面试题53 :正则表达式匹配 Java
引言:这道题情况比较复杂,边界条件较多,为了便于以后复习,整理一下。另外,由于C语言和Java对于字符串的操作存在不一样的地方,代码也存在改动。
题目:请实现一个函数用来匹配包含'.'和'*'的正则表达式。模式中的字符‘.’表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"及"ab*a"均不匹配。
分析:这道题的核心其实在于分析'*',对于'.'来说,它和任意字符都匹配,可把其当做普通字符。对于'*'的分析,我们要进行分情况讨论,当所有的情况都搞清楚了以后,就可以写代码了。
在每轮匹配中,Patttern第二个字符是'*'时:
- 第一个字符不匹配('.'与任意字符视作匹配),那么'*'只能代表匹配0次,比如'ba'与'a*ba',字符串不变,模式向后移动两个字符,然后匹配剩余字符串和模式
- 第一个字符匹配,那么'*'可能代表匹配0次,1次,多次,比如'aaa'与'a*aaa'、'aba'与'a*ba'、'aaaba'与'a*ba'。匹配0次时,字符串不变,模式向后移动两个字符,然后匹配剩余字符串和模式;匹配1次时,字符串往后移动一个字符,模式向后移动2个字符;匹配多次时,字符串往后移动一个字符,模式不变;
而当Patttern第二个字符不是'*'时,情况就简单多了:
- 如果字符串的第一个字符和模式中的第一个字符匹配,那么在字符串和模式上都向后移动一个字符,然后匹配剩余字符串和模式。
- 如果字符串的第一个字符和模式中的第一个字符不匹配,那么直接返回false。
好,现在思路已经清楚了,可以看代码了:
- package test;
- import java.util.Scanner;
- public class Question_53 {
- public static boolean match(String input,String pattern){
- if(input==null||pattern==null) return false;
- return matchCore(input,0,pattern,0);
- }
- private static boolean matchCore(String input,int i,String pattern,int p){
- if((input.length()==i)&&(pattern.length()==p)){
- //出口1,input和pattern都到了字符串末尾
- return true;
- }
- if((i!=input.length())&&(pattern.length()==p)){
- //出口2,字符串input没有到末尾,pattern到了末尾
- return false;
- }
- if((input.length()==i)&&(pattern.length()!=p)){
- //出口3,字符串input到末尾,pattern还没有到末尾
- return false;
- }
- if((p+1<pattern.length())&&(pattern.charAt(p+1)=='*')){//pattern第二个字符为*
- if((input.charAt(i)==pattern.charAt(p))||(pattern.charAt(p)=='.')){
- //首字母相匹配
- return matchCore(input,i+1,pattern,p+2) //*表示出现1次
- ||matchCore(input,i+1,pattern,p) //*表示出现多次
- ||matchCore(input,i,pattern,p+2); //*表示出现0次 , a ... p* ...
- }else{
- //首字母不匹配
- return matchCore(input,i,pattern,p+2);
- }
- } //end pattern.charAt(p+1)=='*'
- if((input.charAt(i)==pattern.charAt(p))||(pattern.charAt(p)=='.')){
- //pattern第二个字母不是*,且首字母匹配
- return matchCore(input,i+1,pattern,p+1);
- }
- return false; //其余情况全部不匹配
- }
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- Scanner scanner = new Scanner(System.in); //扫描键盘输入
- System.out.println(" 请输入第一个字符串:");
- String str1 = scanner.nextLine();
- System.out.println(" 请输入第二个字符串:");
- String str2 = scanner.nextLine();
- scanner.close();
- System.out.print("匹配的结果为:");
- System.out.println(match(str1, str2));
- }
- }
注意边界条件,当模式和字符串都只剩一个字符时, pattern.charAt(p+1)=='*' 会访存越界,所以需要加额外的限制条件 p+1<pattern.length() ,这样这个条件不能满足就会进入下一个if判断语句,直接判断两个字符是不是相等,最后进入出口1,返回true。字符串和模式任意一个先结束都视作不匹配,返回false,这就是出口2和出口3.
《剑指offer》 面试题53 :正则表达式匹配 Java的更多相关文章
- 【剑指Offer】52、正则表达式匹配
题目描述: 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹 ...
- 剑指Offer:面试题34——丑数(java实现)
问题描述: 把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 思路1: ...
- 剑指Offer:面试题16——反转链表(java实现)
问题描述 定义一个函数,输入一个链表的头结点,反转该链表并输出反转后的链表的头结点.链表结点如下: public class ListNode { int val; ListNode next = n ...
- 剑指Offer:面试题15——链表中倒数第k个结点(java实现)
问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...
- 剑指offer面试题3 二维数组中的查找(c)
剑指offer面试题三:
- 剑指Offer——笔试题+知识点总结
剑指Offer--笔试题+知识点总结 情景回顾 时间:2016.9.23 12:00-14:00 19:00-21:00 地点:山东省网络环境智能计算技术重点实验室 事件:笔试 注意事项:要有大局观, ...
- C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告
剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...
- C++版 - 剑指offer 面试题23:从上往下打印二叉树(二叉树的层次遍历BFS) 题解
剑指offer 面试题23:从上往下打印二叉树 参与人数:4853 时间限制:1秒 空间限制:32768K 提交网址: http://www.nowcoder.com/practice/7fe2 ...
- C++版 - 剑指offer 面试题39:判断平衡二叉树(LeetCode 110. Balanced Binary Tree) 题解
剑指offer 面试题39:判断平衡二叉树 提交网址: http://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId= ...
- Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)
剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...
随机推荐
- Daily Scrumming* 2015.10.24(Day 5)
一.总体情况总结 从今天开始,我们开始正式进入紧锣密鼓的集中开发周啦~~加油Fighting~ 开会讨论了一下各个人的细致分工,前端后端各自想成员分派任务. 继续各自领域的准备工作,同时开始进行开发. ...
- 20172332 2017-2018-2 《程序设计与数据结构》Java哈夫曼编码实验--哈夫曼树的建立,编码与解码
20172332 2017-2018-2 <程序设计与数据结构>Java哈夫曼编码实验--哈夫曼树的建立,编码与解码 哈夫曼树 1.路径和路径长度 在一棵树中,从一个结点往下可以达到的孩子 ...
- 20162327WJH第一次实验——线性结构
20162327WJH第一次实验--线性结构 实 验 报 告 实 验 报 告 课程:程序设计与数据结构 班级: 1623 姓名: 王旌含 学号:20162327 成绩: 2分 指导教师:娄嘉鹏 王志强 ...
- 封装,策略,Asp换脸
封装.策略 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespac ...
- IT小小鸟读书笔记(3.9)
对于IT小小鸟呢,我也不知道怎么说,或许一开始我就没想到这是一本集合了众多从事IT工作人员的学习,求职经历.读完这本书,说没什么感触,或许连我自己也不太相信. 在书的一开始邹欣就有说到:兴趣是第一原则 ...
- 团队作业4Alpha冲刺(真.三英战吕布团队)
第一天 2018/6/13 1.1 今日完成任务情况以及遇到的问题. 1.1.1:完成前台部分界面优化,后台进行代码优化 1.1.2团队前台部分js.jquery部分功能实现有难度. 1.2 明天任务 ...
- [并查集] 1118. Birds in Forest (25)
1118. Birds in Forest (25) Some scientists took pictures of thousands of birds in a forest. Assume t ...
- Prism6下的MEF:第一个Hello World
最近看书比较多,正好对过去几年的软件开发做个总结.写这个的初衷只是为了简单的做一些记录. 前言 复杂的应用程序总是面临很多的页面之间的数据交互,怎样创建松耦合的程序一直是多数工程师所思考的问题.诸如依 ...
- Beta版本测试第二天
一. 每日会议 1. 照片 2. 昨日完成工作 登入界面的优化与注册界面的优化,之前的登入界面与注册界面没有设计好,使得登入界面与注册界面并不好看,这次对界面进行了优化.另外尝试了找回密码的功能. 3 ...
- PAT 1054 求平均值
https://pintia.cn/problem-sets/994805260223102976/problems/994805272659214336 本题的基本要求非常简单:给定N个实数,计算它 ...