问题描述

  • 字符串str,模式串exp。
  • 必须保证str中无'.'和'星号'字符,并且exp中'星号'不出现在首位,且无连续两个'星号'。PS星号是字符只是暂时没找到markdown的星号转义字符。
  • '.'可以匹配任意一个字符,'星号'可以匹配0-多个星号前面的一个字符的情况。
  • 输出可否匹配。
  • 例:

    str="abc",exp="a.c" ,true

    str="abc",exp=".星号",true

    str="",exp="..星号",false

解题思路

  • 递归思路写成DP。时间复杂度O(N^2*M), 其中N为str的长度。
  • 具体的,
    • dp[i][j]表示str[i:str.length]能否匹配exp[j:exp.length]
    • 开dp[str.length()+1][exp.length()+1]
    • dp[i][j]只依赖于dp[i+k(k>=0)][j+2]或者dp[i+1][j+1],所以初始化最后一行和最后两列,具体初始化看书,并由右下角开始遍历即可。
    • 分以下情况讨论转移,具体见书P318.
      • 当前位置exp的下一位不是'星号'
      • 当前位置exp的下一位是'星号'
        • 当前字符匹配
        • 当前字符不匹配

代码

public class Main {
public static void main(String args[]) {
String str="";
String exp=".*";
boolean match=isMatch(str,exp);
System.out.println(match);
} public static boolean isMatch(String str,String exp) {
if(!isValid(str,exp)) {
return false;
}
boolean[][] dp=new boolean[str.length()+1][exp.length()+1];
init(dp,str,exp); for(int i=str.length()-1;i>=0;--i) {
for(int j=exp.length()-2;j>=0;--j) {
if(exp.charAt(j+1)!='*') {//下一位是星号
if((str.charAt(i)==exp.charAt(j)||exp.charAt(j)=='.')&&dp[i+1][j+1]) {//
dp[i][j]=true;
}
}
else {//下一位不是星号
for(int ii=i;i<str.length()&&((str.charAt(ii)==exp.charAt(j)||exp.charAt(j)=='.'));++ii) {//当前位置可以匹配 //
if(dp[ii+1][j+2]) {
dp[i][j]=true;
break;
}
}
if(!dp[i][j]) {//当前位置不可以匹配
dp[i][j]=dp[i][j+2];
}
}
}
} return dp[0][0];
} public static boolean isValid(String str,String exp) {
for(int i=0;i<str.length();++i) {
if(str.charAt(i)=='.'||str.charAt(i)=='*') {
return false;
}
}
for(int i=0;i<exp.length();++i) {
if(exp.charAt(i)=='*'&&(i==0)||i!=0&&exp.charAt(i-1)=='*') {
return false;
}
}
return true;
} public static void init(boolean[][] dp,String str,String exp) {
for(int i=0;i<=str.length();++i) {//包含初始化最后一列
for(int j=0;j<=exp.length();++j) {
dp[i][j]=false;
}
}
dp[str.length()][exp.length()]=true; if(str.length()>0&&exp.length()>0) {//初始化倒数第二列 //
if(str.charAt(str.length()-1)==exp.charAt(exp.length()-1)||exp.charAt(exp.length()-1)=='.') {
dp[str.length()-1][exp.length()-1]=true;
}
} for(int j=exp.length()-2;j>=0;j=j-2) {//初始化最后一行
if(exp.charAt(j+1)=='*') {//
dp[str.length()][j]=true;
}
else {
break;
}
}
}
}

[程序员代码面试指南]字符串问题-字符串匹配问题(DP)的更多相关文章

  1. [程序员代码面试指南]字符串问题-回文最少分割数(DP)

    问题描述 给定一个字符串,输出把它全部切成回文子串的最小分割数. 例:str="ACDCDCDAD",输出2. 解题思路 DP 存储结构 dp数组dp[len+1],dp[i]表示 ...

  2. [程序员代码面试指南]最长递增子序列(二分,DP)

    题目 例:arr=[2,1,5,3,6,4,8,9,7] ,最长递增子序列为1,3,4,8,9 题解 step1:找最长连续子序列长度 dp[]存以arr[i]结尾的情况下,arr[0..i]中的最长 ...

  3. 程序员代码面试指南 IT名企算法与数据结构题目最优解

    原文链接 这是一本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现.针对当前程序员面试缺乏权威题目汇总这一痛点,本书选取将近200道真实出现过的经典代码面试题,帮 ...

  4. 程序员代码面试指南:IT名企算法与数据结构题目最优解

      第1章栈和队列 1设计一个有getMin功能的栈(士★☆☆☆) 1由两个栈组成的队列(尉★★☆☆) 5如何仅用递归函数和栈操作逆序一个栈(尉★★☆☆) 8猫狗队列(士★☆☆☆)10用一个栈实现另一 ...

  5. [程序员代码面试指南]递归和动态规划-数字字符串转换为字母组合的种数(DP)

    题意 给一个字符串,只由数字组成,若是'1'-'26',则认为可以转换为'a'-'z'对应的字母,问有多少种转换方法. 题解 状态转移很好想,注意dp多开一位,dp[0]为dp[2]的计算做准备.dp ...

  6. 《程序员代码面试指南》第五章 字符串问题 去掉字符串中连续出现k 个0 的子串

    题目 去掉字符串中连续出现k 个0 的子串 java代码 package com.lizhouwei.chapter5; /** * @Description: 去掉字符串中连续出现k 个0 的子串 ...

  7. [程序员代码面试指南]递归和动态规划-最长公共子串问题(DP,LCST)

    问题描述 如题. 例:输入两个字符串 str1="1AB234",str2="1234EF" ,应输出最长公共子串"234". 解题思路 状 ...

  8. 《程序员代码面试指南》第三章 二叉树问题 判断t1 树中是否有与t2 树拓扑结构完全相同的子树

    题目 判断t1 树中是否有与t2 树拓扑结构完全相同的子树 java代码 package com.lizhouwei.chapter3; /** * @Description: 判断t1 树中是否有与 ...

  9. [程序员代码面试指南]递归和动态规划-最小编辑代价(DP)

    问题描述 输入 原字符串StrOrg,目标字符串StrTarget,插入.删除.替换的编辑代价ic,dc,rc.输出将原字符串编辑成目标字符串的最小代价. 解题思路 状态表示 dp[i][j]表示把s ...

随机推荐

  1. ios 创建sdk与demo同一个工程

    思路摘要: 步骤1:创建一个文件夹用来放该项目 步骤2:设置工程工作区间 步骤3:  创建广告sdk项目 步骤4:创建广告sdkDemo项目 步骤5:配置一些文件 步骤6:将sdk导入到demo中进行 ...

  2. eclipse及idea使用问题记录(为了方便github同步,重新用Markdown写了一篇)

    使用eclipse或idea的时候会遇到各式各样的小问题,解决方案其实网上也大都搜得到,但是下次遇到的时候总是想不起来如何解决,还要花费时间再次查资料.所以以后把遇到的问题都记录一下. @ 目录 Ec ...

  3. three.js 制作逻辑转体游戏(下)

    上一篇已经对绕非定轴转动有所了解,这篇郭先生继续说一说逻辑转体游戏的制作,这部分我们同样会遇到一些小问题,首先是根据数据渲染陷阱和目标区域,然后是对可以转动的判定,最后是获胜的判定. 1. 根据数据渲 ...

  4. 高德地图marker事件监听-高德地图marker绑定事件就执行了[解决立即执行]

    官方的demo是这样的:地址:[http://lbs.amap.com/api/javascript-api/example/infowindow/add-infowindows-to-multipl ...

  5. 精讲响应式WebClient第3篇-POST、DELETE、PUT方法使用

    本文是精讲响应式WebClient第3篇,前篇的blog访问地址如下: 精讲响应式webclient第1篇-响应式非阻塞IO与基础用法 精讲响应式WebClient第2篇-GET请求阻塞与非阻塞调用方 ...

  6. Golang bytes.buffer详解

    原文:https://www.jianshu.com/p/e53083132a25 Buffer 介绍 Buffer 是 bytes 包中的一个 type Buffer struct{…} A buf ...

  7. 构造 IPv6 报文

    #!/usr/bin/python from scapy.all import * a=IPv6(nh=58, src='fe80::214:f2ff:fe07:af0', dst='ff02::1' ...

  8. 《p5.js创意游戏编程》第一课:跳动的小球

    准备:Hbuilder/vscode等可以编写网页的编辑器 如果想立刻上手也可以使用在线编译器p5.js官方在线编辑器,如果打不开也可以使用国内的一款在线编辑器jsrun编辑器,(第一课先使用jsru ...

  9. 华为云配置Objected-based Storage System

    本实验要求基于开源的对象文件系统(例如Ceph),搭建视频点播(VoD)网站.可参考使用Ceph, wordpress, php 以及nginx 实现相关功能,主要包含以下方面: 配置Ceph; 配置 ...

  10. Deep Learning-Based Video Coding: A Review and A Case Study

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! 1.Abstract: 本文主要介绍的是2015年以来关于深度图像/视频编码的代表性工作,主要可以分为两类:深度编码方案以及基于传统编码方 ...