首页 > 编程语言 >KMP算法--解决字符串匹配问题--模式串是否在文本串出现过

KMP算法--解决字符串匹配问题--模式串是否在文本串出现过

时间:2023-08-31 21:55:37浏览次数:58  
标签:匹配 string -- next dest int KMP 文本 charAt

KMP算法--解决字符串匹配问题--模式串是否在文本串出现过 *利用之前判断过的信息,通过next数组保存最长公共子序列的长度 *搜索词/模式串 移动的位数=已匹配的字符数-对应的部分匹配值 在韩的例子里ABCDABD 初次匹配匹配了ABCDAB 6位,对应2,所以移动6-2=4位

e.g.
文本串 aabaabaaf
模式串 aabaaf

模式串的前缀:
    a
    aa
    aab
    aaba
    aabaa

模式串的后缀:
        f
       af
      aaf
     baaf
    abaaf

最长公共子序列的长度:
    a          0  
    aa         1 (a和a)
    aab        0
    aaba       1 (a和a)
    aabaa      2 (a和a,aa和aa)
    aabaaf     0

前缀表:010120

从索引为2的位置开始继续匹配


package LeetcodeExercise;

import java.util.Arrays;

/**
 * @author: JESSICA
 * @description: TODO
 * @date: 2023/8/30 16:52
 * @version: 1.0
 */
public class KMP {
    public static void main(String[] args) {
        String text_string = "BBC ABCDAB ABCDABCDABDE";
        String pattern_string = "ABCDABD";

        int[] next = kmpNext(pattern_string);
        System.out.println(Arrays.toString(next));
        int index = kmpSearch(text_string, pattern_string, next);
        System.out.println(index);
    }


    //获取一个字符串的部分匹配值表
    public static int[] kmpNext(String dest){
        int[] next = new int[dest.length()];
        next[0] = 0;
        for (int i = 1, j = 0; i < dest.length(); i++){
            //找前后缀的相同的字符 当不相等时,令j向前一位 取next[j-1] 从这里更新j
            while(j > 0 && dest.charAt(i) != dest.charAt(j)){
                j = next[j-1];
            }
            //找前后缀的相同的字符 当相等时,j++,即部分匹配值+1
            if(dest.charAt(i) == dest.charAt(j)){
                j++;
            }
            next[i] = j;
        }
        return next;
    }

    public static int kmpSearch(String text_string, String pattern_string, int[] next){
        for(int i = 0, j = 0; i < text_string.length(); i++){
            //不匹配时,j需要重定向--kmp核心
            while (j > 0 && text_string.charAt(i) != pattern_string.charAt(j)){
                j = next[j-1];
            }
            if(text_string.charAt(i) == pattern_string.charAt(j)){
                j++;//相同,继续向后查找
            }
            //j就是在模式串定位 长度一样相当于每一个字符都匹配了
            if(j == pattern_string.length()){
                return i-j+1;
            }
        }
        return -1;
    }



}

标签:匹配,string,--,next,dest,int,KMP,文本,charAt
From: https://www.cnblogs.com/bbnltxdy/p/17670541.html

相关文章

  • linux 磁盘管理常用操作
    理论看前一篇动态扩展:vgs  查看vglvextend -L +10G  /dev/mapper/lv-name    其中lv-name可以通过df -Th查看lvs  查看lvresize2fs    /dev/mapper/lv-name          设置文件系统xfs_growfs  /dev/mapper/lv-name......
  • 【CF1542C】Strange Function(数论)
    题目大意:#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constllmod=1e9+7;lln;lllcm(llx,lly){ returnx/__gcd(x,y)*y;}intmain(){ intT; cin>>T; while(T--){ cin>>n; llans=n%mod; for(lli=1,j=1;n/j......
  • 手写raft(三) 实现日志压缩
    手写raft(三)实现日志压缩在上一篇博客中MyRaft实现了日志复制功能,按照计划接下来需要实现日志压缩。手写raft(一)实现leader选举手写raft(二)实现日志复制1.什么是raft日志压缩?我们知道raft协议是基于日志复制的协议,日志数据是raft的核心。但随着raft集群的持续工作,ra......
  • Java - ThreadPoolExecutor线程池分析
    Java- ThreadPoolExecutor源码分析 1.为什么要自定义线程池首先ThreadPoolExecutor中,一共提供了7个参数,每个参数都是非常核心的属性,在线程池去执行任务时,每个参数都有决定性的作用。但是如果直接采用JDK提供的方式去构建,可见设置的核心参数最多就两个,这样就会导致对线程池......
  • 全方面深入探索 Flutter,手把手带你走向封神之路
    前言在不断发展的技术环境中,Flutter已成为简化移动应用程序开发的首选框架。Flutter由Google开发,具有从精美的UI到更短的开发周期等一系列优势,使其成为全球开发者的首选。Flutter优势1、语言优势Flutter使用Dart语言作为开发语言,Dart本身的优势就在于,它既支持JIT,又支持AOT;......
  • 计网(概述)
    网络、互联网和因特网的区别与关系若干节点和链路互连形成网络若干网络通过路由器互连形成互联网因特网是世界上最大的互联网电路交换、报文交换、和分组交换的对比若要连续传送大量的数据,并且数据传送时间远大于建立连接的时间,则使用电路交换可以有较好的传输效率。......
  • 习题纠错03
    表达式"X=A+B(C-D)/E"的后缀表示形式可以是()//答案是CAXAB+CDE/-=BXA+BC-DE/=CXABCD-E/+=DXABCDE+/=//从左到右边遍历这个中缀表达式//X添加到后缀表达式,=入栈,A添加到后缀表达式中//+进入栈,B进入后缀表达式,和(入栈,C进入后缀表达式中//-进入栈,D进入后缀表达式,遇到),-和(出栈......
  • redis7.2.0 centos源码编译安装并设置开机自启动
    下载源码包wgethttps://github.com/redis/redis/archive/7.2.0.tar.gztar-zxf7.2.0.tar.gz编译编码编译编码cdredis-7.2.0make&&makeinstall此时默认redis-serverredis-cli等命令行安装到目录/usr/local/bin/目录中。如果你想安装命令行到指定目录中你可以指定......
  • print ("标签为" + str(train_set_y[:, index]) + ", 这是一个'" + classes[np.squeez
    这行代码使用 print 函数来输出一条信息。信息的内容是由多个字符串拼接而成的,其中包括 train_set_y 数组中指定索引处的值和 classes 数组中指定索引处的值。首先,"标签为" 是一个字符串字面量。接下来,str(train_set_y[:,index]) 表示获取 train_set_y 数组中第二维索......
  • 分页PageInterceptor
    依赖引入<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>xx.xx.xx</version></dependency>编码PageHelper.startPage()在查询前执行,设置Page放入ThreadLocal中/......