怎么在java项目中实现一个公里算法

  介绍

怎么在java项目中实现一个公里算法?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

公里算法是一种神奇的字符串匹配算法,在对超长字符串进行模板匹配的时候比暴力匹配法的效率会高不少。接下来我们从思路入手理解公里算法。

在对字符串进行匹配的时候我们最容易想到的就是一个个匹配,类似下面这种:

怎么在java项目中实现一个公里算法

换成java代码就是:

public  static  boolean  bfSearch (String  String 模式;txt) {   ,,,if  (txt.length (), & lt;, pattern.length ())   ,,,,,return 假;   ,,,for  (int 小姐:=,0;,小姐:& lt;, txt.length();,我+ +),{   ,,,,,boolean  flag =,假;   ,,,,,for  (int  j =, 0;, j  & lt;, pattern.length ();, j + +), {   ,,,,,,,if  (i + j>=txt.length ())   ,,,,,,,,,return 假;   ,,,,,,,if  (txt.charAt (i + j) !=pattern.charAt (j)) {   ,,,,,,,,,flag =,真的;   ,,,,,,,}   ,,,,,}   ,,,,,if (国旗){   ,,,,,,,return 真实;   ,,,,,}   ,,,}   ,,,return 假;   以前,,}

暴力匹配算法的时间复杂度为O (n * m), n为模板字符串,m为目标字符串,在处理复杂字符串时毫无疑问效率会非常低,由此诞生了公里算法(时间复杂度为O (m + n))。

以上面gif图中的两个字符串

txt=癮aacaaab”

帕特=癮aab”

为例我们来说一小时下公里算法的思路。个人能力有限,您可以先行观看此视频去简单学习公里的基本原理。

简单原理:构建状态转移数组,当遇到无法匹配的字符时根据状态转移数组进行回溯,以达到减少遍历次数的目的。

1。首先构建状态转移数组:

对匹配模式字符串进行遍历
从左向右遍历,如果i和j(见源码)所指向的元素相同,则将此状态(j所指向的元素位置)进行保存
最后保存的数组是一个Int类型的状态码数组,每个元素的含义是回溯时模板字符串(模式)的状态。

2。构建完成后通过状态转移数组和匹配模式字符串对传入的目标字符串进行匹配。过程如下:

对目标字符串进行遍历,检索相同的字符元素。
如果遇到不同的字符元素,根据J(模板字符串的指针)所在的位置依靠状态转移数组来回溯遍历状态。并在回溯后继续进行匹配。

3。源码如下:

import  java.util.Arrays;      public  class  KMP  {   private 才能,int [], patArray;,//,状态转移数组   private 才能;final  String 模式;//,匹配模式字符串   public 才能static  boolean  bfSearch (String  String 模式;txt) {   ,,,if  (txt.length (), & lt;, pattern.length ()) return 假;   ,,,for  (int 小姐:=,0;,小姐:& lt;, txt.length();,我+ +),{   ,,,,,boolean  flag =,假;   ,,,,,for  (int  j =, 0;, j  & lt;, pattern.length ();, j + +), {   ,,,,,,,if  (i + j>=txt.length ()) return 假;   ,,,,,,,if  (txt.charAt (i + j) !=pattern.charAt (j)) {   ,,,,,,,,,flag =,真的;   ,,,,,,,}   ,,,,,}   ,,,,,if (国旗){   ,,,,,,,return 真实;   ,,,,,}   ,,,}   ,,,return 假;   ,,}   公里才能(String 帕特),{,//通过匹配模式字符串构建对象   ,,,this.pattern =,帕特;   ,,,patArray =, new  int [pattern.length()];,//,创建状态转移数组   ,,,int  j =, 0;   ,,,for  (int 小姐:=,1;,小姐:& lt;, pattern.length ();,), {   ,,,,,if  (pattern.charAt (i),==, pattern.charAt (j)) {,   ,,,,,,,//,如果i和j指向的字符相同,则将此状态进行保存   ,,,,,,,patArray (+ +),=, + + j,,//,保存的同时移步下一位   ,,,,,}else  {   ,,,,,,,//,如果,小姐:和,j 指向的字符不相同,则保持我不动,回溯j   ,,,,,,,//,如果回溯后的j指向的字符与我相同,则将此时的状态进行保存   ,,,,,,,if  (j  & lt;=, pattern.length(),安康;1,,,,j 在0),{   ,,,,,,,,,j=patArray [- j];,//,回溯j   ,,,,,,,,,if  (pattern.charAt (i),==, pattern.charAt (j)), {,   ,,,,,,,,,,,//,如果回溯后相同,则保存状态   ,,,,,,,,,,,patArray (+ +),=, + + j;   ,,,,,,,,,}   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

怎么在java项目中实现一个公里算法