【算法】字符串匹配算法

news/2024/10/22 4:07:38/

字符串匹配算法

    • KMP算法
    • Booyer-Moore算法

KMP算法

KMP算法在匹配失败时总是将j设为某个值以使i不回退。在查找过程的开始,从文本的开头进行查找,起始状态为0,它停留在0状态并扫描文本,直到找到一个和模式的首字母相同的字符。这是它移动到下一个状态并开始运行。在这个过程的最后,当它找到一个匹配时,它会不断地匹配模式中的字符和文本,自动机的状态会不断前进直到状态M。每次匹配成功会将DFA带入下一个状态,匹配失败会使DFA回到较早之前的状态。

public class KMP {private String pat;private int[][] dfa;public KMP(String pat) {this.pat = pat;int M = pat.length();int R = 256;dfa[pat.charAt(0)][0] = 1;for (int x = 0, j = 1; j < M; ++j) {for (int c = 0; c < R; ++c) {dfa[c][j] = dfa[c][x]; // 设置匹配失败情况下的值}dfa[pat.charAt(j)][j] = j + 1; // 设置匹配成功情况下的值x = dfa[pat.charAt(j)][x]; // 更新匹配到j时的重启状态}}public int search(String txt) {int i, j, N = txt.length();int M = pat.length();for (i = 0, j = 0; i < N && j < M; ++i) {j = dfa[txt.charAt(i)][j];}if (j == M) return i - M;else return N;}
}

Booyer-Moore算法

使用right[]记录字母表中的每个字符在模式中出现的最靠右的地方(如果字符在模式中不存在则表示为-1)。这个值揭示了如果该字符出现在文本中且在查找时造成一次匹配失败应该向右跳跃多远。计算完right[]数组之后,我们用一个索引i在文本中从左向右移动,用另一个索引j在模式中从右往左移动。内循环会检查正文和模式字符串在位置i是否一致。如果从M-1到0的所有j,txt.charAt(i + j)都和pat.charAt(j)相等,那么就找到了一个匹配。否则匹配失败,就会遇到以下三种情况:

  1. 如果造成匹配失败的字符不包含在模式字符串中,模式字符串向右移动 j + 1 个位置(即将i增加 j + 1)。小于这个偏移量只可能使该字符与模式中的某个字符重叠。事实上,这次移动也会将模式字符串前面一部分已知的字符和模式结尾的一部分已知字符对齐。通过预先计算一张类似于KMP算法的表格,还可以将i的值变得更大。
  2. 如果造成匹配失败的字符包含在模式字符串中,那就可以使用right[]数组来将模式字符串和文本对齐,使得该字符和它在模式字符串中出现的最右位置相匹配。和刚才一样,小于这个偏移量只可能使该字符和模式中的与它无法匹配的字符(比它出现的最右边位置更靠右的字符)重叠。我们可以用一张类似于KMP算法的表格将 i 变得更大。
  3. 如果这种方式无增大i,那就直接将i加1来保证模式字符串至少向右移动了一个位置。
public class BooyerMoore {private int[] right;private String pat;BooyerMoore (String pat) {this.pat = pat;int M = pat.length();int R = 256;right = new int[R];for (int c = 0; c < R; ++c) {right[c] = -1;}for (int j = 0; j < M; ++j) {right[pat.charAt(j)] = j;}}public int search(String txt) {int N = txt.length();int M = pat.length();int skip;for (int i = 0; i < N - M; i += skip) {skip = 0;for (int j = M - 1; j >= 0; --j) {skip = j - right[txt.charAt(i + j)];if (skip < 1) skip = 1;break;}if (skip == 0) return i;}return N;}}

http://www.ppmy.cn/news/1000608.html

相关文章

一次有趣的Webshell分析经历

一次有趣的Webshell分析经历 1.拉取源代码2.解密后门代码3.分析webshell逻辑4.分析404的原因5.附&#xff1a;格式化后的php代码 1.拉取源代码 在对某目标做敏感目录收集时发现对方网站备份源代码在根目录下的 backup.tar.gz&#xff0c;遂下载&#xff0c;先使用D盾分析有没有…

Canvas好难,如何让研发低成本实现Web端流程图设计功能

摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 相信大家在职场中经常会用到流程图&#xff0c;在互联网行业&#xff0c;绘制流…

计算机视觉与图形学-神经渲染专题-第一个基于NeRF的自动驾驶仿真平台

如今&#xff0c;自动驾驶汽车可以在普通情况下平稳行驶&#xff0c;人们普遍认识到&#xff0c;真实的传感器模拟将在通过模拟解决剩余的极端情况方面发挥关键作用。为此&#xff0c;我们提出了一种基于神经辐射场&#xff08;NeRF&#xff09;的自动驾驶模拟器。与现有作品相…

五、JVM-垃圾回收算法

常见的回收算法&#xff1a;标记清除算法、复制算法、标记-整理算法、分代收集算法 1、标记清除算法 第一步&#xff1a;标记&#xff08;找出内存中需要回收的对象&#xff0c;并且把它们标记出来&#xff09; 第二步&#xff1a;清除 &#xff08;清除掉被标记需要回收的对…

实现邮箱管理之gmail邮箱、office365(Azure)邮箱之披荆斩棘问题一览

要进行Office365邮箱的授权对接&#xff0c;你需要先申请一个应用&#xff0c;并获取授权访问令牌。 以下是一个简单的步骤&#xff1a; 登录 Azure 门户&#xff1a;https://portal.azure.com/创建一个新的应用程序&#xff0c;或者使用现有的应用程序。要创建新的应用程序&…

数据库监控平台,数据库监控的指标有哪些--PIGOSS BSM

引言 在现代企业的信息化时代&#xff0c;数据库作为关键的数据存储和管理工具&#xff0c;扮演着至关重要的角色。然而&#xff0c;数据库的稳定性和高效性对于企业的正常运营至关重要。为了帮助企业保障数据库的运行状态&#xff0c;我们公司推出了PIGOSS BSM&#xff0c;一款…

【腾讯云 Cloud Studio 实战训练营】云上编程,彻底释放电脑物理内存

文章目录 前言一、快速上手1、账号注册2、新建工作空间3、配置工作空间参数4、工作空间展示5、运行飞机大战代码 二、空间模板三、应用推荐1、点击 Fork2、等待工作空间启动3、安装 Dependencies4、运行 App 总结 前言 腾讯云推出的 Cloud Studio 是基于浏览器的集成式开发环境…

【物理】带电粒子在磁场和电场中移动的 3D 轨迹研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…