字符串中的KMP算法及其改进

简介: 字符串中的KMP算法及其改进

公众号merlinsea


  • 字符串的定义
  • 字符串是由0个或者多个字符组成的有限序列,其中字符串中字符的个数称之为串的长度,含有0个字符的串也称之为空串。
  • 字符串的基本操作
  • 赋值操作
  • 取串的长度操作
  • 串的比较操作
  • 求子串操作
  • 清空串的操作
  • 字符串的模式匹配问题
  • 假设有一个主串s 和 一个待匹配的子串p,请问在主串p中能否找到子串s。
  • 解题思路1:双重for循环遍历,然后判断子串p是否出现在子串s中。


public class Main {
    public static void main(String[] args) {
        String s = "abcdsaegsdkjflakji"; // 原串
        String p = "gsdk1"; // 模式串
        boolean res = false;
        for(int i=0;i<=s.length()-p.length();i++){
            int j = 0;
            while(j<p.length()){
                if(p.charAt(j)==s.charAt(i+j)){
                    j++;
                }else{
                    break;
                }
            }
            if(j==p.length()){
                res = true;
                break;
            }
        }
        if(res){
            System.out.println(s + " 包含了 " +p);
        }else{
            System.out.println(s + " 不包含 " +p);
        }
    }
}


  • 算法复杂度分析
  • 时间复杂度O(p.length * s.length)
  • 恐空间复杂度O(1)


  • KMP算法
  • 解法一的字符串匹配问题的时间复杂度是O(p.length * s.length),可以发现这个时间复杂度还是比较高的,那么有没有什么方法可以优化字符串匹配问题呢,下面我们介绍一下字符串的模式匹配算法KMP。

640.png

  • KMP算法介绍
  • 模式匹配算法假设当前不匹配的元素发生在子串p的第i个位置,即子串的[0,i-1]位置是和主串匹配的。
  • 然后我们计算出子串新的下标 i 的位置。
  • 接着我们通过next的数组来决定应该如何移动模式串p。


640.png


  • KMP算法的实现


public class Main {
    public static void main(String[] args) {
        String p = "ABABABB";
        String s = "ABAAABABABBAABBA";
        int[] next = kmp(p);
        System.out.printf("next数组=");
        for(int k : next){
            System.out.printf("%d \t",k);
        }
        System.out.println();
        int i = 0;
        int j = 0;
        while(j<p.length() && i<s.length()){
            if(p.charAt(j) == s.charAt(i)){
                i++;
                j++;
            }else{
                j = next[j]-1;
                if(j<0){
                    j = 0;
                    i++;
                }
            }
        }
        //判断匹配是否成功
        boolean res = j==p.length();
        System.out.println("主串s = "+s);
        System.out.println("子串p = "+p);
        if(res){
            System.out.println("匹配成功");
        }else{
            System.out.println("匹配失败");
        }
    }
    /**
     * next数组是第几个元素,因此n从1开始
     */
    public static int[] kmp(String p){
        int[] next = new int[p.length()];
        next[0]=0;
        /**
         * 当前不匹配元素发生在i位置
         */
        for(int i=1;i<p.length();i++){
            /**
             * 子串向右移动的距离为step
             */
           int step = 1;
           while(step<=i){
               /**
                * 子串的新下标
                */
               int idxSon = 0;
               /**
                * 主串的新下标
                */
               int idxPar = step;
               while(idxPar<i){
                   if(p.charAt(idxPar) == p.charAt(idxSon)){
                       idxPar++;
                       idxSon++;
                   }else{
                       break;
                   }
               }
               /**
                * 说明之前匹配成功了
                */
               if(idxPar == i){
                   next[i] = i-step+1;
                   break;
               }
               step++;
           }
        }
        return next;
    }
}


  • KMP算法的改进
  • 模式匹配算法假设当前不匹配的元素发生在子串p的第i个位置,从这个地方我们还可以推导出主串p对应子串s的位置不是什么元素。


640.png


相关文章
|
3天前
|
自然语言处理 算法 搜索推荐
字符串相似度算法完全指南:编辑、令牌与序列三类算法的全面解析与深入分析
在自然语言处理领域,人们经常需要比较字符串,这些字符串可能是单词、句子、段落甚至是整个文档。如何快速判断两个单词或句子是否相似,或者相似度是好还是差。这类似于我们使用手机打错一个词,但手机会建议正确的词来修正它,那么这种如何判断字符串相似度呢?本文将详细介绍这个问题。
172 1
|
5天前
|
数据采集 算法 JavaScript
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
JavaScript字符串搜索涵盖`indexOf`、`includes`及KMP算法。`indexOf`返回子字符串位置,`includes`检查是否包含子字符串。KMP是高效的搜索算法,尤其适合长模式匹配。示例展示了如何在数据采集(如网页爬虫)中使用这些方法,结合代理IP进行安全搜索。代码示例中,搜索百度新闻结果并检测是否含有特定字符串。学习这些技术能提升编程效率和性能。
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
|
4天前
|
算法 Java
KMP算法详解及其在字符串匹配中的应用
KMP算法详解及其在字符串匹配中的应用
|
4天前
|
算法 Java
KMP算法详解及其在字符串匹配中的应用
KMP算法详解及其在字符串匹配中的应用
|
7天前
|
人工智能 算法 BI
一篇文章讲明白KMP算法(俗称看毛片算法)
一篇文章讲明白KMP算法(俗称看毛片算法)
10 0
|
2天前
|
机器学习/深度学习 算法 调度
Matlab|基于改进鲸鱼优化算法的微网系统能量优化管理matlab-源码
基于改进鲸鱼优化算法的微网系统能量管理源码实现,结合LSTM预测可再生能源和负荷,优化微网运行成本与固定成本。方法应用于冷热电联供微网,结果显示经济成本平均降低4.03%,提高经济效益。代码包括数据分段、LSTM网络定义及训练,最终展示了一系列运行结果图表。
|
7天前
|
算法 安全 数据库
基于结点电压法的配电网状态估计算法matlab仿真
**摘要** 该程序实现了基于结点电压法的配电网状态估计算法,旨在提升数据的准确性和可靠性。在MATLAB2022a中运行,显示了状态估计过程中的电压和相位估计值,以及误差随迭代变化的图表。算法通过迭代计算雅可比矩阵,结合基尔霍夫定律解决线性方程组,估算网络节点电压。状态估计过程中应用了高斯-牛顿或莱文贝格-马夸尔特法,处理量测数据并考虑约束条件,以提高估计精度。程序结果以图形形式展示电压幅值和角度估计的比较,以及估计误差的演变,体现了算法在处理配电网状态估计问题的有效性。
|
4天前
|
数据采集 存储 算法
基于BP算法的SAR成像matlab仿真
**摘要:** 基于BP算法的SAR成像研究,利用MATLAB2022a进行仿真。SAR系统借助相对运动合成大孔径,提供高分辨率图像。BP算法执行回波数据预处理、像素投影及图像重建,实现精确成像。优点是高精度和强适应性,缺点是计算量大、内存需求高。代码示例展示了回波生成、数据处理到插值显示的全过程。
|
11天前
|
机器学习/深度学习 自然语言处理 算法
m基于深度学习的OFDM+QPSK链路信道估计和均衡算法误码率matlab仿真,对比LS,MMSE及LMMSE传统算法
**摘要:** 升级版MATLAB仿真对比了深度学习与LS、MMSE、LMMSE的OFDM信道估计算法,新增自动样本生成、复杂度分析及抗频偏性能评估。深度学习在无线通信中,尤其在OFDM的信道估计问题上展现潜力,解决了传统方法的局限。程序涉及信道估计器设计,深度学习模型通过学习导频信息估计信道响应,适应频域变化。核心代码展示了信号处理流程,包括编码、调制、信道模拟、降噪、信道估计和解调。
38 8
|
5天前
|
算法 vr&ar
基于自适应波束成形算法的matlab性能仿真,对比SG和RLS两种方法
```markdown - MATLAB2022a中比较SG与RLS自适应波束成形算法。核心程序实现阵列信号处理,强化期望信号,抑制干扰。RLS以其高效计算权重,而SG则以简单和低计算复杂度著称。[12345] [6666666666] [777777] ```