【Offer】[19] 【字符串匹配】
题目描述
请实现一个函数用来匹配包括'.'
和'*'
的正则表达式。 模式中的字符'.'表示任意一个字符,而'*'
表示它前面的字符可以出现任意次(包含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。 例如,字符串"aaa"
与模式"a.a"
和"ab*ac*a"
匹配,但是与"aa.a"
和"ab*a"
均不匹配
思路分析
使用递归函数 matchCore(char[] str, int i, char[] pattern, int j)
来比较索引i,j
位置上的字符是否匹配,大体分为两种情况:
- 当前字符的下一个字符不是
*
时,如果当前字符相等,则继续调用函数比较下一字符,i
和j
索引都+1
,不相等则返回false
- 当前字符的下一个字符是
*
时,如果当前字符不相等,这时将模式串索引j+2(跳过a*
),继续比较;如果相等:- 字符串的索引i+1,匹配串索引j+2
- 字符串的索引i+1,匹配串索引不变
- 字符串的索引不变,匹配串索引j+2 (例如
ba*ac
) 可以跳过a*
测试用例
- 功能测试(模式中包含普通字符、“.”、“*”;匹配情况;不匹配情况)
- 特殊测试(null,空字符串)
Java代码
public class Offer19 {
public static void main(String[] args) {
test1();
test2();
}
public static boolean match(char[] str, char[] pattern) {
return Solution1(str, pattern);
}
/**
* 方法1
* @param str 字符串
* @param pattern 模式串
* @return
*/
private static boolean Solution1(char[] str, char[] pattern) {
if(str == null || pattern == null) {
return false;
}
return matchCore(str,0,pattern, 0);
}
/**
* 字符串匹配的核心算法:
*
* @param str 字符串
* @param i 字符串当前索引
* @param pattern 模式串
* @param j 模式串当前索引
* @return
*/
private static boolean matchCore(char[] str, int i, char[] pattern, int j) {
if(i==str.length && j==pattern.length) {
return true;
}
if(i<str.length && j==pattern.length) {
return false;
}
if(j+1<pattern.length && pattern[j+1] == '*') {
if((i<str.length && (str[i] == pattern[j]) || pattern[j]=='.')) {
//这里需要判断字符串和匹配串当前字符是否相等, 如果模式串当前字符为'.',也为相等
return matchCore(str,i+1,pattern,j+2)
|| matchCore(str, i+1, pattern, j)
|| matchCore(str, i, pattern, j+2); // 如果模式串是 ba*ac这种情况 a*是可以直接跳过的
}else {
return matchCore(str,i,pattern,j+2); // 当前字符不相等,可以直接跳过a*
}
}
//这里要放在后面
if(i<str.length && (str[i]==pattern[j] || pattern[j]=='.')) {
return matchCore(str, i+1, pattern, j+1);
}
return false;
}
/**
* 此测试程序参考自 剑指Offer一书中的源码[https://github.com/zhedahht/CodingInterviewChinese2]
* @param testName
* @param str
* @param pattern
* @param expected
*/
private static 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!");
}
/**
* 功能测试
*/
private static void test1() {
char[] str1 = "aaa".toCharArray();
char[] str2 = "aaa".toCharArray();
char[] pattern1 = "a*.b*b*aa".toCharArray();
char[] pattern2 ="ab*ac*a".toCharArray();
test("aaa,a*.b*b*aa --->", str1, pattern1, true);
test("aaa,ab*ac*a--->", str2, pattern2, true);
char[] str3 = {'a'};
char[] pattern3 = {'.','*'};
test("a, .* -->", str3, pattern3, true);
}
/**
* 特殊测试
*/
private static void test2() {
char[] str = {};
char[] pattern = null;
test("{},null --->", str, pattern, false);
}
}
代码链接
【Offer】[19] 【字符串匹配】的更多相关文章
- 剑指 Offer 19. 正则表达式匹配 + 动态规划
剑指 Offer 19. 正则表达式匹配 题目链接 一. 字符串匹配大致可以分为三种情况: 第一种:正则串的最后一个字符为正常字符,此时根据主串的最后一个字符是否和它相同来判断是否匹配, 如果相同,则 ...
- 字符串匹配--Karp-Rabin算法
主要特征 1.使用hash函数 2.预处理阶段时间复杂度O(m),常量空间 3.查找阶段时间复杂度O(mn) 4.期望运行时间:O(n+m) 本文地址:http://www.cnblogs.com/a ...
- 字符串匹配--kmp算法原理整理
kmp算法原理:求出P0···Pi的最大相同前后缀长度k: 字符串匹配是计算机的基本任务之一.举例,字符串"BBC ABCDAB ABCDABCDABDE",里面是否包含另一个字符 ...
- 【Java编程】Java中的字符串匹配
在Java中,字符串的匹配可以使用下面两种方法: 1.使用正则表达式判断字符串匹配 2.使用Pattern类和Matcher类判断字符串匹配 正则表达式的字符串匹配: ...
- "《算法导论》之‘字符串’":字符串匹配
本文主要叙述用于字符串匹配的KMP算法. 阮一峰的博文“字符串匹配的KMP算法"将该算法讲述得非常形象,可参考之. 字符串‘部分匹配值’计算 KMP算法重要的一步在于部分匹配值的计算.模仿& ...
- 字符串匹配的KMP算法
~~~摘录 来源:阮一峰~~~ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”? 许 ...
- {Reship}{KMP字符串匹配}
关于KMP字符串匹配的介绍和归纳,作者的思路非常清晰,推荐看一下 http://blog.csdn.net/v_july_v/article/details/7041827
- 字符串匹配(hash算法)
hash函数对大家来说不陌生吧 ? 而这次我们就用hash函数来实现字符串匹配. 首先我们会想一下二进制数. 对于任意一个二进制数,我们将它化为10进制的数的方法如下(以二进制数1101101为例): ...
- 【C++实现python字符串函数库】二:字符串匹配函数startswith与endswith
[C++实现python字符串函数库]字符串匹配函数startswith与endswith 这两个函数用于匹配字符串的开头或末尾,判断是否包含另一个字符串,它们返回bool值.startswith() ...
随机推荐
- Activiti6系列(2)- 运行和编译
前言 Activiti6.0在官网已经无法下载了,需要在Github上下载. 下载地址: https://github.com/Activiti/Activiti/releases/download/ ...
- vue面试题整理vuejs基础知识整理
初级参考 1.v-show 与 v-if 区别 v-show 是css隐藏,v-if是直接销毁和创建,所以频繁切换的适合用v-show 2.计算属性和 watch 的区别 计算属性是自动监听依赖值的变 ...
- 统计学习方法—SVM推导
目录 SVM 1. 定义 1.1 函数间隔和几何间隔 1.2 间隔最大化 2. 线性可分SVM 2.1 对偶问题 2.2 序列最小最优算法(SMO) 3. 线性不可分SVM 3.1 松弛变量 3.2 ...
- form提交的几种方式
背景 一直使用postman作为restful接口的调试工具,但是针对post方法的几种类型,始终不明白其含义,今天彻底了解了下 form提交的来源 html页面上的form表单 <form a ...
- JavaFx应用 星之小说下载器
星之小说下载器 说明: 需要jdk环境 目前只支持铅笔小说网,后续添加更多书源,还有安卓版,敬请期待. 喜欢的话,不妨打赏一波! 软件交流QQ群:690380139 断点下载暂未实现,小说下载途中,一 ...
- vue中的虚拟DOM树
什么是虚拟DOM树?(Virtual DOM) 虚拟DOM树其实就是一个普通的js对象,它是用来描述一段HTML片段的 01 当页面渲染的时候Vue会创建一颗虚拟DOM树 02 ...
- java之面向对象详解
#############java面向对象详解#############1.面向对象基本概念2.类与对象3.类和对象的定义格式4.对象与内存分析5.封装性6.构造方法7.this关键字8.值传递与引用 ...
- 解决Springboot整合ActiveMQ发送和接收topic消息的问题
环境搭建 1.创建maven项目(jar) 2.pom.xml添加依赖 <parent> <groupId>org.springframework.boot</group ...
- SpringMVC 原理 - 设计原理、启动过程、请求处理详细解读
SpringMVC 原理 - 设计原理.启动过程.请求处理详细解读 目录 一. 设计原理 二. 启动过程 三. 请求处理 一. 设计原理 Servlet 规范 SpringMVC 是基于 Servle ...
- JMM浅析
背景 学习Java并发编程,JMM是绕不过的槛.在Java规范里面指出了JMM是一个比较开拓性的尝试,是一种试图定义一个一致的.跨平台的内存模型.JMM的最初目的,就是为了能够支多线程程序设计的,每个 ...