当前位置: 首页 > news >正文

数据结构与算法系列之kmp算法

在这里插入图片描述

什么是kmp算法

1.kmp算法是一种改进的字符串算法,其核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数已达到快速匹配的目的。
它主要实现作用的是 在 (主串)中找到 (匹配)字符串

在这里插入图片描述

BF算法与kmp算法的差别

bf算法如下所示 从首元素字符开始依次比较 ,如果相同则比较下一位元素,如果匹配失败 ,匹配字符串从头开始 ,主串从第二个字符开始比较,直到主字符串全部匹配完。如果匹配成功返回主字符串中第一次出现匹配字符串的位置。

在这里插入图片描述
在这里插入图片描述

kmp算法如下所示,kmp与bf不一样的地方在于:主串的所指向的字符不会后退,匹配串中所指向的也不会移动到首字符位置

在这里插入图片描述

在这里插入图片描述

kmp的回退规则,next数组的介绍

目的是使 指向主串字符不会回退 ,匹配串回退到一个特定位置
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这就是next数组的来源
规定next[0]=-1 next[1]=0
在这里插入图片描述

回退前提 : p[i] == p[k] 则 p[i] == p[k] next[i+1] == k+1 ,如果 p[i] != p[k] 则 next[k] != k, k==next[k] ,一直回退直到p[i] == p[k]

p[i] == p[k] 如下
在这里插入图片描述
p[i] != p[k]如下

在这里插入图片描述

kmp算法代码实现(C语言版)

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
void GetNext(char*sub, int* next ,int LenSub)
{next[0] = -1;next[1] = 0;int k = 0;int i = 2;while(i < LenSub){if (k == -1 || sub[i - 1] == sub[k]){next[i] = k + 1;i++;k++;}else{k = next[k];}}
}
int KMP(char* str, char* sub, int pos)
{assert(str  && sub );int LenStr = strlen(str);int LenSub = strlen(sub);if (LenStr == 0 || LenSub == 0)return -1;if (pos < 0 || pos >= LenStr)return -1;int* next = (int*)malloc(sizeof(int) * LenSub);assert(next);GetNext(sub, next,LenSub);int i = pos;//主串int j = 0;//字串while (i < LenStr && j < LenSub){if (j == -1 || str[i] == sub[j]){i++;j++;}else{j = next[j];}}if (j >= LenSub)return i - j;return -1;
}int main()
{printf("%d", KMP("ababcabcdabcde", "abcd", 0));return 0;
}

在这里插入图片描述

http://www.lryc.cn/news/15089.html

相关文章:

  • 算法分析详解
  • 东南大学自然辩证法概论期末总结
  • 《爆肝整理》保姆级系列教程python接口自动化(二十)--token登录(详解)
  • k8s种的kubectl命令
  • 数组(一)-- LeetCode[26][80] 删除有序数组中的重复元素
  • GEE学习笔记 六十三:新的地图图层ui.Map.CloudStorageLayer
  • ClickHouse 语法详解
  • 手把手教你将微信小程序放到git上
  • 功能测试3年,回顾一路走来的艰辛
  • 作为Linux C/C++程序员必备的工具
  • docker Alpine一个只有5M小而美的Docker镜像
  • Springboot扩展点之InstantiationAwareBeanPostProcessor
  • 基于 U-Net 网络的遥感图像语义分割 完整代码+论文
  • Codeql 编译Shiro1.2.4爬坑
  • 新C++(9):谈谈,翻转那些事儿
  • Java深克隆的几种方式
  • PointNet++的源码运行
  • npm 上传自己的包
  • 【Linux】常用命令大全(二)
  • 第一章 操作系统概述
  • ChatGPT为什么不受开发者喜欢?
  • Lua table
  • JavaScript:使用for in不是一个很好的抉择
  • Go语言学习小笔记(一)
  • 前端Docker部署方案
  • Java——无重叠区间
  • 数据库和数据表创建与管理操作
  • buu [ACTF新生赛2020]crypto-rsa3 1
  • 知识库:在医疗行业的知识管理有着怎样的意义与实际影响?
  • 带你一步步搭建Web自动化测试框架