【Java】 剑指offer(19) 正则表达式匹配
本文参考自《剑指offer》一书,代码采用Java语言。
题目
请实现一个函数用来匹配包含'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"及"ab*a"均不匹配。
思路
使用函数matchCore(char[] str, int indexOfStr, char[] pattern, int indexOfPattern) 来实现每一步的比较(递归)。
(1)当模式中第二个字符不为“*”时:若当前字符相等,则字符串和模式都后移一个字符,继续调用函数进行比较;若不相等,则返回false。
(2)当模式中第二个字符为“*”时:若当前字符不相等,则模式后移两个字符,继续比较;若当前字符相等,则有三种情况:
1)字符串字符位置不变,模式后移两个字符,继续比较; //x*被忽略
2)字符串后移一个字符,模式后移两个字符,继续比较;
3)字符串后移一个字符,模式字符位置不变,继续比较。
三种情况使用“||”进行并列比较。
注意点
时刻要注意数组是否越界!
测试算例
1.功能测试(模式中包含普通字符、“.”、“*”;匹配情况;不匹配情况)
2.特殊测试(null,空字符串)
完整Java代码
(含测试代码)
package _19; /**
*
* @Description 面试题19:正则表达式匹配
*
* @author yongh
* @date 2018年9月21日 上午8:12:06
*/ // 题目:请实现一个函数用来匹配包含'.'和'*'的正则表达式。模式中的字符'.'
// 表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。在本题
// 中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"
// 和"ab*ac*a"匹配,但与"aa.a"及"ab*a"均不匹配。 public class RegularExpressions {
public boolean match(char[] str, char[] pattern) {
if (str == null || pattern == null)
return false;
return matchCore(str, 0, pattern, 0);
} private boolean matchCore(char[] str, int indexOfStr, char[] pattern, int indexOfPattern) {
if (indexOfStr == str.length && indexOfPattern == pattern.length)
return true;
if (indexOfStr < str.length && indexOfPattern == pattern.length)
return false;
if (indexOfPattern + 1 < pattern.length && pattern[indexOfPattern + 1] == '*') {
if ((indexOfStr < str.length && pattern[indexOfPattern] == '.')
|| (indexOfStr < str.length && pattern[indexOfPattern] == str[indexOfStr])) {
return matchCore(str, indexOfStr, pattern, indexOfPattern + 2)
|| matchCore(str, indexOfStr + 1, pattern, indexOfPattern)
|| matchCore(str, indexOfStr + 1, pattern, indexOfPattern + 2);
} else {
return matchCore(str, indexOfStr, pattern, indexOfPattern + 2);
}
}
if (indexOfStr < str.length && (pattern[indexOfPattern] == str[indexOfStr] || pattern[indexOfPattern] == '.'))
return matchCore(str, indexOfStr + 1, pattern, indexOfPattern + 1);
return false;
} // ==========测试代码=========
void test(String testName, char[] str, char[] pattern, boolean expected) {
System.out.print(testName + ":");
if (match(str, pattern) == expected)
System.out.println("passed!");
else
System.out.println("failed!");
} void test1() {
char[] str = {};
char[] pattern = { '.' };
test("test1", str, pattern, false);
} void test2() {
char[] str = {};
char[] pattern = { '.', '*' };
test("test2", str, pattern, true);
} void test3() {
char[] str = { 'a' };
char[] pattern = { '.', '*' };
test("test3", str, pattern, true);
} void test4() {
char[] str = {};
char[] pattern = {};
test("test4", str, pattern, true);
} void test5() {
char[] str = null;
char[] pattern = null;
test("test5", str, pattern, false);
} void test6() {
char[] str = { 'a', 'b', 'b' };
char[] pattern = { 'a', 'b', 'b', '*', 'b' };
test("test6", str, pattern, true);
} void test7() {
char[] str = { 'a' };
char[] pattern = { 'a', 'a', '*' };
test("test7", str, pattern, true);
} public static void main(String[] args) {
RegularExpressions demo = new RegularExpressions();
demo.test1();
demo.test2();
demo.test3();
demo.test4();
demo.test5();
demo.test6();
demo.test7();
}
}
test1:passed!
test2:passed!
test3:passed!
test4:passed!
test5:passed!
test6:passed!
test7:passed!
RegularExpressions
收获
1.涉及到数组的情况下,一定要时刻注意数组越界问题!
2.对于每一步都是采用相同判断方法的题目,可以采用递归函数来实现
3.思维一定要全面,把握住关键矛盾,将每种情况考虑清楚。例如这道题,关键就在于第二个字符是否为“*”,确定关键问题后,分析清楚每一种情况即可
4.代码第29行的 indexOfStr < str.length 一定要记得加,否则可能会出现重复执行第32行的情况。
【Java】 剑指offer(19) 正则表达式匹配的更多相关文章
- 剑指 Offer 19. 正则表达式匹配 + 动态规划
剑指 Offer 19. 正则表达式匹配 题目链接 一. 字符串匹配大致可以分为三种情况: 第一种:正则串的最后一个字符为正常字符,此时根据主串的最后一个字符是否和它相同来判断是否匹配, 如果相同,则 ...
- 剑指 Offer 19. 正则表达式匹配
题目描述 请实现一个函数用来匹配包含'. '和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次).在本题中,匹配是指字符串的所有字符匹配整个模式. ...
- 剑指offer:正则表达式匹配
目录 题目 解题思路 具体代码 题目 题目链接 剑指offer:正则表达式匹配 题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符.表示任意一个字符,而*表示它前面的字符可以 ...
- Go语言实现:【剑指offer】正则表达式匹配
该题目来源于牛客网<剑指offer>专题. 请实现一个函数用来匹配包括 . 和 * 的正则表达式.模式中的字符.表示任意一个字符,而 * 表示它前面的字符可以出现任意次(包含0次). 在本 ...
- 剑指Offer 52. 正则表达式匹配 (字符串)
题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式 ...
- [剑指Offer] 52.正则表达式匹配
题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式 ...
- 剑指offer——21正则表达式匹配
题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式 ...
- 剑指offer52:正则表达式匹配
1 题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符‘.’表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个 ...
- 剑指offer(19)二叉树中和为某一值的路径
题目: 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.(注意: 在返回值的list中,数组长度大的 ...
随机推荐
- android app与服务器交互
package mydemo.mycom.demo2.service; import org.apache.http.HttpResponse; import org.apache.http.Name ...
- Python3之网络爬虫<0>初级
由于Python3合并URLib与URLlib2统一为URLlib,Python3将urlopen方法放在了urllib.request对象下. 官方文档:https://docs.python.or ...
- JavaScript学习 - 基础(三) - 运算符
js运算符 1.算数运算符 包括 加(+) .减-() .乘(*).除(/).余数(%) 减号 还可以表示为 负号 例如: -1,-3 加号 还可以用于字符串拼接 例如: 'a' + 'b' = 'a ...
- 一套oracle的练习题
create table student( sno varchar2(10) primary key, sname varchar2(20), sage number(2), ssex varchar ...
- jQuery-contextMenu使用教程
jQuery-contextMenu使用教程 效果如下图所示.在[右击菜单]处右击,会出现下面的效果. 添加引用 <script src="jQuery-contextMenu-mas ...
- 为caffe添加最简单的全通层AllPassLayer
参考赵永科的博客,这里我们实现一个新 Layer,名称为 AllPassLayer,顾名思义就是全通 Layer,“全通”借鉴于信号处理中的全通滤波器,将信号无失真地从输入转到输出. 虽然这个 Lay ...
- Shell脚本中执行sql语句操作mysql的5种方法【转】
对于自动化运维,诸如备份恢复之类的,DBA经常需要将SQL语句封装到shell脚本.本文描述了在Linux环境下mysql数据库中,shell脚本下调用sql语句的几种方法,供大家参考.对于脚本输出的 ...
- phantomjs 下拉滚动条获取网页的全部源码
//codes.js var system = require('system'); var fs = require("fs"); //console.log('Loading ...
- 使用nginx实现浏览器跨域请求
跨域访问问题, 相信很多人都遇到过, 并且都用不同的办法去解决过. 方法有很多种, 不一一叙述了. 这里主要使用nginx反向代理来解决跨域问题. 啥是跨域? 假如你是百度开发人员, 在百度页面去请求 ...
- VS2017编译boost库
1.http://www.boost.org/ 下载boost库. 2.解压到 D:\ProgramFiles\boost 3.环境配变量配置 VS2017更加注重跨平台性,安装文件较 ...