题目描述

  请实现一个函数用来匹配包括'.''*'的正则表达式。 模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含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. 【Python】狂蟒来袭 | 使用Anaconda搭建Python开发环境

    这段时间转了一个小圈圈,发现又回来了,瞎忙.想要学习数据挖掘的小伙伴一定得对机器学习有所了解吧,我之前看过几页周志华老师的西瓜书,但终没能坚持下来. 人生处处是起点,什么时候都不晚.记此笔记以分享与督 ...

  2. GD32电压不足时烧写程序导致程序运行异常的解决方法

    一直使用的GD32F450前段时间遇到这样一个问题,当使用J-Link供电给板子烧写程序之后,程序运行缓慢,就像运行在FLASH高速部分之外一样,但是如果使用外部供电烧写,就不会出现这个问题,而且一旦 ...

  3. ABAP 查看采购订单行项目已开票金额和已清金额

    FUNCTION zmm_fm_po_invence. *"----------------------------------------------------------------- ...

  4. 基于Spring Boot自建分布式基础应用

    目前刚入职了一家公司,要求替换当前系统(单体应用)以满足每日十万单量和一定系统用户负载以及保证开发质量和效率.由我来设计一套基础架构和建设基础开发测试运维环境,github地址. 出于本公司开发现状及 ...

  5. net start mysql

    net start mysql 解决的方法: 如何以管理员身份打开黑窗口 左下角开始菜单,找到小娜,cmd 回车, 命令提示符右击,以管理员身份打开 依次输入下面两行代码 mysqld -instal ...

  6. ‎Cocos2d-x 学习笔记(21) ScrollView (CCScrollView)

    1. 简介 CCScrollView.cpp文件内的滚动视图ScrollView直接继承了Layer+ActionTweenDelegate. 滚动视图能在屏幕区域内,用户通过触摸拖动屏幕,实现大于屏 ...

  7. UVA 10098 用字典序思想生成所有排列组合

    题目: Generating permutation has always been an important problem in computer science. In this problem ...

  8. 图灵学院Java架构师-VIP-【性能调优-Mysql索引数据结构详解与索引优化】

    最近报名了图灵学院的架构专题的付费课程,没有赶上6月份开课,中途加入的.错过了多线程的直播课程,只能看录播了

  9. Mybatis的一级缓存和二级缓存的理解以及用法

    程序中为什么使用缓存? 先了解一下缓存的概念:原始意义是指访问速度比一般随机存取存储器快的一种RAM,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术.对于我们编程来说,所谓的 ...

  10. JavaScript数组方法详解

    JavaScript数组方法详解 JavaScript中数组的方法种类众多,在ES3-ES7不同版本时期都有新方法:并且数组的方法还有原型方法和从object继承的方法,这里我们只介绍数组在每个版本中 ...