题目描述

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

思路分析

  使用递归函数 matchCore(char[] str, int i, char[] pattern, int j)
来比较索引i,j位置上的字符是否匹配,大体分为两种情况:

  1. 当前字符的下一个字符不是*时,如果当前字符相等,则继续调用函数比较下一字符,ij索引都+1,不相等则返回false
  2. 当前字符的下一个字符是*时,如果当前字符不相等,这时将模式串索引j+2(跳过a*),继续比较;如果相等:
    • 字符串的索引i+1,匹配串索引j+2
    • 字符串的索引i+1,匹配串索引不变
    • 字符串的索引不变,匹配串索引j+2 (例如ba*ac) 可以跳过a*

测试用例

  1. 功能测试(模式中包含普通字符、“.”、“*”;匹配情况;不匹配情况)
  2. 特殊测试(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代码-Java

【Offer】[19] 【字符串匹配】的更多相关文章

  1. 剑指 Offer 19. 正则表达式匹配 + 动态规划

    剑指 Offer 19. 正则表达式匹配 题目链接 一. 字符串匹配大致可以分为三种情况: 第一种:正则串的最后一个字符为正常字符,此时根据主串的最后一个字符是否和它相同来判断是否匹配, 如果相同,则 ...

  2. 字符串匹配--Karp-Rabin算法

    主要特征 1.使用hash函数 2.预处理阶段时间复杂度O(m),常量空间 3.查找阶段时间复杂度O(mn) 4.期望运行时间:O(n+m) 本文地址:http://www.cnblogs.com/a ...

  3. 字符串匹配--kmp算法原理整理

    kmp算法原理:求出P0···Pi的最大相同前后缀长度k: 字符串匹配是计算机的基本任务之一.举例,字符串"BBC ABCDAB ABCDABCDABDE",里面是否包含另一个字符 ...

  4. 【Java编程】Java中的字符串匹配

    在Java中,字符串的匹配可以使用下面两种方法:         1.使用正则表达式判断字符串匹配         2.使用Pattern类和Matcher类判断字符串匹配 正则表达式的字符串匹配: ...

  5. "《算法导论》之‘字符串’":字符串匹配

    本文主要叙述用于字符串匹配的KMP算法. 阮一峰的博文“字符串匹配的KMP算法"将该算法讲述得非常形象,可参考之. 字符串‘部分匹配值’计算 KMP算法重要的一步在于部分匹配值的计算.模仿& ...

  6. 字符串匹配的KMP算法

    ~~~摘录 来源:阮一峰~~~ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”? 许 ...

  7. {Reship}{KMP字符串匹配}

    关于KMP字符串匹配的介绍和归纳,作者的思路非常清晰,推荐看一下 http://blog.csdn.net/v_july_v/article/details/7041827

  8. 字符串匹配(hash算法)

    hash函数对大家来说不陌生吧 ? 而这次我们就用hash函数来实现字符串匹配. 首先我们会想一下二进制数. 对于任意一个二进制数,我们将它化为10进制的数的方法如下(以二进制数1101101为例): ...

  9. 【C++实现python字符串函数库】二:字符串匹配函数startswith与endswith

    [C++实现python字符串函数库]字符串匹配函数startswith与endswith 这两个函数用于匹配字符串的开头或末尾,判断是否包含另一个字符串,它们返回bool值.startswith() ...

随机推荐

  1. Activiti6系列(2)- 运行和编译

    前言 Activiti6.0在官网已经无法下载了,需要在Github上下载. 下载地址: https://github.com/Activiti/Activiti/releases/download/ ...

  2. vue面试题整理vuejs基础知识整理

    初级参考 1.v-show 与 v-if 区别 v-show 是css隐藏,v-if是直接销毁和创建,所以频繁切换的适合用v-show 2.计算属性和 watch 的区别 计算属性是自动监听依赖值的变 ...

  3. 统计学习方法—SVM推导

    目录 SVM 1. 定义 1.1 函数间隔和几何间隔 1.2 间隔最大化 2. 线性可分SVM 2.1 对偶问题 2.2 序列最小最优算法(SMO) 3. 线性不可分SVM 3.1 松弛变量 3.2 ...

  4. form提交的几种方式

    背景 一直使用postman作为restful接口的调试工具,但是针对post方法的几种类型,始终不明白其含义,今天彻底了解了下 form提交的来源 html页面上的form表单 <form a ...

  5. JavaFx应用 星之小说下载器

    星之小说下载器 说明: 需要jdk环境 目前只支持铅笔小说网,后续添加更多书源,还有安卓版,敬请期待. 喜欢的话,不妨打赏一波! 软件交流QQ群:690380139 断点下载暂未实现,小说下载途中,一 ...

  6. vue中的虚拟DOM树

    什么是虚拟DOM树?(Virtual DOM)   虚拟DOM树其实就是一个普通的js对象,它是用来描述一段HTML片段的    01    当页面渲染的时候Vue会创建一颗虚拟DOM树 02    ...

  7. java之面向对象详解

    #############java面向对象详解#############1.面向对象基本概念2.类与对象3.类和对象的定义格式4.对象与内存分析5.封装性6.构造方法7.this关键字8.值传递与引用 ...

  8. 解决Springboot整合ActiveMQ发送和接收topic消息的问题

    环境搭建 1.创建maven项目(jar) 2.pom.xml添加依赖 <parent> <groupId>org.springframework.boot</group ...

  9. SpringMVC 原理 - 设计原理、启动过程、请求处理详细解读

    SpringMVC 原理 - 设计原理.启动过程.请求处理详细解读 目录 一. 设计原理 二. 启动过程 三. 请求处理 一. 设计原理 Servlet 规范 SpringMVC 是基于 Servle ...

  10. JMM浅析

    背景 学习Java并发编程,JMM是绕不过的槛.在Java规范里面指出了JMM是一个比较开拓性的尝试,是一种试图定义一个一致的.跨平台的内存模型.JMM的最初目的,就是为了能够支多线程程序设计的,每个 ...