《剑指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 ...
随机推荐
- 20135234mqy
北京电子科技学院(BESTI) 实 验 报 告 课程:Java实验 班级:1352 姓名: mqy 学号:20135234 成绩: 指导教师 ...
- install4j 工具为java程序打包exe
用 install4j 工具为java程序打包exe 制作人:mark 制作时间:2013-05-02 用Eclipse 将程序源码打包成jar文件. 打包jar方法我不做介绍了,相信大家都会,不会的 ...
- sprint初步计划(第一天)
一.现状 小组成员初步了解四则运算程序编写大概内容,进行简单的讨论.只知道大概的流程,实际还没做出.现在明确目标是把我们写Java的四则运算变成一个手机APP,关于手机ap,我们还不是很了解,所以需要 ...
- mysql EXPLAIN 参数表
测试样式: 参数详情:
- SqlServer日期时间函数
-- 判断是否当天,createdate为日期字段 -- ╔════════════════════╗ -- ============================================= ...
- [C/C++] 输入函数getline(cin,str) 与cin.getline(str,int)区别
cin.getline()函数是处理数组字符串的,其原型为cin.getline(char * , int),第一个参数为一个char指针,第二个参数为数组字符串长度. getline(cin,str ...
- 使用 TClientDataSet(1)
本例效果图: 代码文件: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, ...
- Lottie开源库实现Android动画效果
Lottie简介 Lottie是一个支持Android.iOS.React Native,并由Adobe After Effects制作aep格式的动画,然后经由bodymovin插件转化渲染为jso ...
- forEach遍历数组对象且去重
forEach遍历数组对象 var obj1 = [{ key: '01', value: '哈哈' }, { key: '02', value: '旺旺' }, { key: '03', value ...
- 使用URLConnection发送http请求实现简单爬虫(可以配置代理)
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import jav ...