字符串匹配

模板:

KMP:

细节在代码中

看不懂的可以参照:如何更好地理解和掌握 KMP 算法? - 阮行止的回答 - 知乎
https://www.zhihu.com/question/21923021/answer/1032665486

package StringMatch.KMP;import java.util.ArrayList;
import java.util.List;public class KMP {/*** 计算p在s中所有匹配子串的开始位置* @param s 主串* @param p 模式串* @return 所有匹配子串的开始位置*/public List<Integer> search(String s,String p){ArrayList<Integer> ans = new ArrayList<>();char[] sch = s.toCharArray();char[] pch = p.toCharArray();int[] next = buildNext(p);int count = 0;for (int i = 0; i < sch.length; i++) {while(count > 0 && pch[count] != sch[i]){// 回退到上一轮可以复用的前缀的长度count = next[count-1];}if( pch[count] == sch[i]){count++;}if(count == pch.length){ans.add(i-pch.length+1);// 复用整个模式串的k-前/后缀长度count = next[count-1];}}return ans;}private int[] buildNext(String p){char[] ch = p.toCharArray();int plen = ch.length;int[] next = new int[plen];/*注意next[i]的值不可能是i+1,选取整个子串对跳过失败位置没有任何帮助例如abcabcd,匹配到d错了,此时看前方next[5]=3,即前五位正确,并且3前缀=3后缀然后向后挪动三位 也就是用第二个abc去匹配第一个abc但如果选取整个子串 next[5] = 6,这样向后挪动6位,就从d那一位开始匹配了反而错过了第二个abc,导致可能的错误*/next[0] = 0;for(int i=1;i<plen;i++){// 先找到上一位匹配的k的长度int prev = next[i - 1];// 若上一轮匹配的k的后面一位等于当前这一位,相当于可以扩展一位/*例如,abcdabc,i=7,ch[7] = d既然要看这一轮的最大k,那么检查上一轮的k=3,说明ch[0,6]中 ch[0,2] 与 ch[4,6]是相等的这样如果 ch[3] = ch[7] = d,就可以在ch[0,2] = ch[4,6]上扩展一位变成 ch[0,3] = ch[4,7]*/if(ch[prev]==ch[i]){next[i] = prev + 1;}/*若不等于,我们也不一定要从0再开始。举个例子abcabd dd abcab, i=13 ch[13] = c那么 c!= ch [ next[13-1] ] = ch[5] = d但 c = ch[ next[4] ]啊 那么这个4怎么来的?由于next[12] = 5,即ch[0,12]的5前缀等于5后缀 也就是说ch[0,4] = ch[8,12]那么我们想求最大的K,使得 ch[0,k-1] = ch[13-k+1,13]其中这个K很显然<5,不然就直接匹配上了,变成第一种情况了,也就是ch[13] = ch[5]了可以检查 next[4] ,也就是ch[0,4]中的最大K,这里是2 也即 ch[0,1] = ab = ch[3,4]又因为ch[0,4] = ch[8,12] 所以 ch[0,1] = ch[11,12]这个next[ next[13-1] - 1 ] = 2,就是本轮算上ch[13] = c之前的最大匹配长度所以 next[13] = 2+1 = 3可以用反证法证明假设存在3<k<5,使得ch[0,k-1] = ch[13-k+1,13]那么必有 abca = cabc,矛盾*/else{/*如果得知ch[0,next[i-1]-1]中的最大K值,也就是next[ next[i-1]-1 ],为0,*/int pnxtk = next[Math.max(next[i - 1] - 1, 0)];next[i] = 0;if(ch[i]==ch[pnxtk]){next[i] = pnxtk + 1;}}}return next;}}

1. LC 3008 找出数组中的美丽下标Ⅱ

思路比较简单:

  1. KMP找出所有匹配的a模式串开始索引
  2. … b模式串 …
  3. 由于KMP查找是顺序的,所以索引也是顺序的,对于任意一个index∈kmp(a),对kmp(b)二分查找即可

这道题就是教kmp板子的(周赛的时候不会板子直接T了捏

import java.util.ArrayList;
import java.util.List;class Solution {static int interval;public List<Integer> beautifulIndices(String s, String a, String b, int k) {interval = k;char[] sch = s.toCharArray();char[] ach = a.toCharArray();char[] bch = b.toCharArray();ArrayList<Integer> ans = new ArrayList<>();List<Integer> ares = kmp(sch, ach);List<Integer> bres = kmp(sch, bch);if(bres.isEmpty()){return ans;}for (Integer num : ares) {int bs = bs(num, bres);if(check(bs,num)){ans.add(num);}}return ans;}private int bs(int index,List<Integer> bres){int lp,rp,mid,ans;lp = 0;rp = bres.size();ans = -interval-1;while(lp<rp){mid = ((rp-lp)>>>1)+lp;Integer num = bres.get(mid);ans = Math.abs(num-index)<Math.abs(ans-index)?num:ans;if(num==index){return index;}else if(num<index){lp = mid+1;}else{rp = mid;}}return ans;}private boolean check(int i,int j){return Math.abs(i-j)<=interval;}private List<Integer> kmp(char[] sch,char[] pch){ArrayList<Integer> ans = new ArrayList<>();int[] next = buildNext(pch);int count = 0;for (int i = 0; i < sch.length; i++) {while(count > 0 && pch[count] != sch[i]){count = next[count-1];}if( pch[count] == sch[i]){count++;}if(count == pch.length){ans.add(i-pch.length+1);count = next[count-1];}}return ans;}private int[] buildNext(char[] pch){int[] next = new int[pch.length];next[0] = 0;for(int i=1;i<pch.length;i++){int prev = next[i - 1];if(pch[prev] == pch[i]){next[i] = prev+1;}else{int j = next[Math.max(next[i - 1] - 1, 0)];if(pch[j]==pch[i]){next[i] = j+1;}else{next[i] = 0;}}}return next;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/627144.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

k8s的配置资源管理

Secret Secret用来保存密码、token密钥以及一些敏感的k8s资源。这类数据虽然可以存放在镜像当中&#xff0c;但是放在secret当中可以更方便控制。减少暴露的风险。 Secret的作用&#xff1a;保存加密的信息 Secret的类型 docker-registry()主要用于存储docker仓库的认证信息…

后台生成随机验证码验证登录

web get请求获取图片 <div class"p2"><img id"imgId" src"/get/code"><a href"#">看不清&#xff0c;换一张</a> </div> 后台代码: /*获取动态验证码*/ ResponseBody RequestMapping(value "/…

【MATLAB源码-第113期】基于matlab的孔雀优化算法(POA)机器人栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 POA&#xff08;孔雀优化算法&#xff09;是一种基于孔雀羽毛开屏行为启发的优化算法。这种算法模仿孔雀通过展开其色彩斑斓的尾羽来吸引雌性的自然行为。在算法中&#xff0c;每个孔雀代表一个潜在的解决方案&#xff0c;而…

人工智能专业必须需要考哪些证书呢?

我们来看看2024年人工智能专业的企业和个人都在紧张报考的两项AI认证证书报考&#xff1a; 为进一步贯彻落实中共中央印发《关于深化人才发展体制机制改革的意见》和国务院印发《关于“十四五”数字经济发展规划》等有关工作的部署要求&#xff0c;深入实施人才强国战略和创新驱…

程序员的职业生涯

程序员的职业生涯一般会经历以下几个阶段&#xff1a; 初级阶段&#xff1a;在这个阶段&#xff0c;程序员通常刚从大学毕业&#xff0c;或者只拥有很少的工作经验。他们开始学习如何编写代码&#xff0c;理解编程语言和开发工具&#xff0c;并熟悉软件开发流程。这个阶段的程…

Django教程第5章 | Web开发实战-数据统计图表(echarts、highchart)

专栏系列&#xff1a;Django学习教程 前言 highchart&#xff0c;国外。 echarts&#xff0c;国内。 本项目集成 hightchart和echarts图表库实现数据统计功能。 包括&#xff1a;折线图&#xff0c;柱状图&#xff0c;饼图和数据集图。 效果图 echats Highcharts 源代码…

java 判断中文英文正则表达式 排除 除了中文以外的特殊字符,排除除了英文以外的特殊字符

boolean containsChinese Pattern.matches(".*[\\u4e00-\\u9fa5].*", names);//containsChinese&#xff1a; true 包含中文就直接把其他特殊字符英文去掉if (containsChinese) {names names.replaceAll("[^\\u4E00-\\u9FA5]", "");//使用正则…

odoo17 | 编码规范大全

编码规范 本页介绍Odoo编码指南。这些旨在改善 Odoo应用程序代码的质量。事实上&#xff0c;适当的代码可以提高可读性&#xff0c;简化 维护&#xff0c;帮助调试&#xff0c;降低复杂性并提高可靠性。 这些准则应适用于每个新模块和所有新开发。 警告 在稳定版本中修改现有…

程序员如何保持竞争力

在程序员的职业生涯中&#xff0c;保持竞争力是非常重要的&#xff0c;因为技术行业不断发展和变化。以下是一些建议&#xff0c;可以帮助程序员保持竞争力&#xff1a; 持续学习新技术和编程语言&#xff1a;技术行业的发展非常快&#xff0c;新的编程语言和技术不断涌现。作为…

易点易动设备管理系统:提升企业设备能耗管理效率的不二之选

在当前环保意识日益增强的社会背景下&#xff0c;企业对设备能耗管理的重视程度不断提升。有效的能耗管理不仅可以减少企业的能源消耗和环境污染&#xff0c;还能降低生产成本和提升竞争力。为了帮助企业实现高效的设备能耗管理&#xff0c;易点易动设备管理系统应运而生。本文…

高级分布式系统-第15讲 分布式机器学习--概念与学习框架

高级分布式系统汇总&#xff1a;高级分布式系统目录汇总-CSDN博客 分布式机器学习的概念 人工智能蓬勃发展的原因&#xff1a;“大” 大数据&#xff1a;为人工智能技术的发展奠定了坚实的物质基础。 大规模机器学习模型&#xff1a;具备超强的表达能力&#xff0c;可以解决…

通过IDE和jar包运行时加载json配置文件

程序中使用了json配置文件&#xff0c;位置在$rootPath/src/main/resources/config.json, 调试时使用IDE&#xff0c;但运行时使用Jar包&#xff0c;加载config.json配置文件的代码如下&#xff1a; public ConfigParser(String configFileName) throws IOException {try{Inp…

安全运维:cmd命令大全(108个)

1、calc&#xff1a;启动计算器 2、appwiz.cpl&#xff1a;程序和功能 3、certmgr.msc&#xff1a;证书管理实用程序 4、charmap&#xff1a;启动字符映射表 5、chkdsk.exe&#xff1a;Chkdsk磁盘检查(管理员身份运行命令提示符) 6、cleanmgr: 打开磁盘清理工具 7、clico…

中国丙烯酸酯橡胶行业研究与投资预测报告(2024版)

内容简介&#xff1a; 丙烯酸弹性体&#xff08;Acrylic elastomer&#xff09;是含有丙烯酸烷基酯成分的丙烯酸类合成橡胶&#xff0c;按照ASTM D1418&#xff0c;丙烯酸弹性体有两种类型&#xff0c;丙烯酸酯橡胶和乙烯-丙烯酸酯弹性体&#xff0c;在它们之后又有乙烯-乙酸乙…

Go语言干货系列:错误处理的最佳实践与技巧

今天&#xff0c;我们就要一同探索在Go语言中&#xff0c;如何优雅地处理错误。 1. Go的错误处理思路 Go语言采用了一种简单而独特的错误处理机制。它鼓励明确地检查错误&#xff0c;而不是依赖异常机制。 基本规则&#xff1a; 函数通常会返回一个值和一个错误对象。 如果…

O2066PM无线WIFI6E网卡Windows环境吞吐测试

从2023年开始&#xff0c;除手机外的无线终端设备也逐步向WIFI6/6E进行升级更新&#xff0c;基于802.11ax技术的设备能够进一步满足用户体验新一代Wi-Fi标准时获得优质的性能和覆盖范围。 用户对于WIFI模块&#xff0c;通常会关注WIFI模块的吞吐量&#xff0c;拿到样品之后&am…

Access数据库模糊查询

Access数据库模糊查询的方法 1.使通配符: 在 Access 数据库中&#xff0c;有两种通配符可供使用&#xff0c;分别是"?"和"*"。 "?"表示匹配一个字符。 "*"表示匹配任意多个字符 1例如&#xff1a;如果要查询姓氏以"王"开…

基于DNA的密码学和隐写术综述

摘要 本文全面调研了不同的脱氧核糖核酸(DNA)-基于密码学和隐写术技术。基于DNA的密码学是一个新兴领域,利用DNA分子的大规模并行性和巨大的存储容量来编码和解码信息。近年来,由于其相对传统密码学方法的潜在优势,如高存储容量、低错误率和对环境因素的抗性,该领域引起…

Linux例行性工作 at和crontab命令

1&#xff0c;例行性工作 例行性工作 —— 在某一时刻&#xff0c;必须要做的事情 —— 定时任务 &#xff08;比如&#xff1a;闹钟&#xff09; 例行性工作分为两种&#xff1a;“单一的例行性工作 at”和“循环的例行性工作 crontab” 2&#xff0c;单一执行的例行性工作 …

【PostgreSQL】数据查询-组合查询(UNION,INTERSECT,EXCEPT)

PostgreSQL数据查询-组合查询&#xff08;UNION,INTERSECT,EXCEPT&#xff09; PostgreSQL可以使用集合运算并集、交集和差值来组合两个查询的结果。语法是 query1 UNION [ALL] query2 query1 INTERSECT [ALL] query2 query1 EXCEPT [ALL] query2其中 query1 和 query2 是可以…