1. /**
  2. * 看了 b站视频 BV1jb411V78H 对KMP有了一点理解,然后我写了这个代码
  3. * 这个代码和视频里面的有一点不同,字符串是从 0 开始的,而不是从1 开始的
  4. * 希望能够帮到学习KMP的人
  5. */
  6. #include <stdbool.h>
  7. #include <malloc.h>
  8. #include "KMP.h"
  9. // KMP.h 内容
  10. /*
  11. #define MAXSIZE (255)
  12. typedef struct {
  13. char ch[MAXSIZE + 1];
  14. int length;
  15. }SString;
  16. void Next(SString const *t);
  17. extern int *next;
  18. int IndexOf_KMP(SString const *s, SString const *t);
  19. */
  20. int *next; // 计算 next数组
  21. /**
  22. * 计算 0-based 模式串t的next数组
  23. * @param t 模式串
  24. */
  25. void Next(SString const *t) {
  26. // 模式串 0 开始
  27. int length = t->length;
  28. // 分配 next数组 所需要的空间
  29. next = (int *)malloc(sizeof(int) * length);
  30. for (int *p = next; p < next + length; p++)
  31. {
  32. *p = 0;
  33. }
  34. for (int i = 0; i < length; i++)
  35. {
  36. if (i <= 1) // 前两个next[i]置为-1
  37. {
  38. next[i] = -1;
  39. continue;
  40. }
  41. // 执行下面的语句的时候, 一定有 i >= 2
  42. int maxlen = 0; // 存储最长公共前后缀的长度
  43. /**
  44. * // len 表示前缀或后缀的最大长度, 可取的值是 [1..i-1] // i 为(模式串或next数组)的访问下标
  45. * 这里主要是 对 模式串在i位置 求 它的最大公共前后缀的长度
  46. * 从 1 开始 到 i-1 一个一个去试
  47. *
  48. */
  49. for (int len = 1; len < i; len++)
  50. {
  51. int val = 0;
  52. bool flag = false;
  53. for (int j = 0, k = i - len; j < len; j++, k++)
  54. {
  55. if (t->ch[j] == t->ch[k])
  56. {
  57. }
  58. else
  59. {
  60. flag = true; // len 长度的公共前后缀匹配失败
  61. break;
  62. }
  63. }
  64. if (flag == false) // 公共前后缀长度为len
  65. val = len;
  66. if (val > maxlen) // 这个比较不是必须的,因为找公共前后缀的长度的时候, len 从 1 到 i-1
  67. maxlen = val; // maxlen 就是 next[i]的值了
  68. }
  69. next[i] = maxlen;
  70. }
  71. }
  72. // 调用这个函数之前,一定要调用 Next函数,为模式串构建 next数组
  73. int IndexOf_KMP(SString const *s, SString const *t)
  74. {
  75. // 开始匹配
  76. int i = 0, j = 0; // i 表示主串的下标, j 表示模式串的下标
  77. while (i < s->length)
  78. {
  79. if (j == -1 || s->ch[i] == t->ch[j])
  80. {
  81. i++;
  82. j++;
  83. }
  84. else
  85. {
  86. j = next[j];
  87. }
  88. // 匹配成功
  89. if (j == t->length)
  90. {
  91. return i - t->length;
  92. }
  93. }
  94. // 匹配失败
  95. return -1;
  96. }

模式串 从 0 开始的KMP算法的更多相关文章

  1. 串匹配模式中的BF算法和KMP算法

    考研的专业课以及找工作的笔试题,对于串匹配模式都会有一定的考察,写这篇博客的目的在于进行知识的回顾与复习,方便遇见类似的题目不会纠结太多. 传统的BF算法 传统算法讲的是串与串依次一对一的比较,举例设 ...

  2. 数据结构(十六)模式匹配算法--Brute Force算法和KMP算法

    一.模式匹配 串的查找定位操作(也称为串的模式匹配操作)指的是在当前串(主串)中寻找子串(模式串)的过程.若在主串中找到了一个和模式串相同的子串,则查找成功:若在主串中找不到与模式串相同的子串,则查找 ...

  3. 字符串与模式匹配算法(三):KMP算法

    一.KMP算法介绍 KMP算法与前面的MP算法一脉相承,都是充分利用先前匹配的过程中已经得到的结果来避免频繁回溯.回顾一下MP算法,如下图的模式串偏移,当前模式字符串P的左端的p0与目标字符串T中tj ...

  4. 字符串模式匹配之KMP算法的next数组详解与C++实现

    相信来看next数组如何求解的童鞋已经对KMP算法是怎么回事有了一定的了解,这里就不再赘述,附上一个链接吧:https://www.cnblogs.com/c-cloud/p/3224788.html ...

  5. (原创)白话KMP算法(续)

    第二章:KMP改良算法 第一章里面我们讲完了KMP算法的next数组实现法,回忆一下其实最重要的内容无非就是一.理解 i 指针无用回溯的意义,二.理解 j 指针的定位和模式串中每个元素重复度的关系,三 ...

  6. Java数据结构之字符串模式匹配算法---KMP算法2

    直接接上篇上代码: //KMP算法 public class KMP { // 获取next数组的方法,根据给定的字符串求 public static int[] getNext(String sub ...

  7. 串的匹配:朴素匹配&amp;KMP算法

    引言 字符串的模式匹配是一种经常使用的操作. 模式匹配(pattern matching),简单讲就是在文本(text,或者说母串str)中寻找一给定的模式(pattern).通常文本都非常大.而模式 ...

  8. KMP算法-Java实现

    目的: 为了解决字符串模式匹配 历程: 朴素模式匹配:逐次进行比较 KMP算法:利用匹配失败得到的信息,来最大限度的移动模式串,以此来减少比较次数提高性能 概念: m:是目标串长度 n:是模式串长度 ...

  9. 【模式匹配】KMP算法的来龙去脉

    1. 引言 字符串匹配是极为常见的一种模式匹配.简单地说,就是判断主串\(T\)中是否出现该模式串\(P\),即\(P\)为\(T\)的子串.特别地,定义主串为\(T[0 \dots n-1]\),模 ...

随机推荐

  1. linux网络配置及虚拟机连接不上网排错思路

    第1章          操作系统与虚拟软件的使用 1.1  虚拟软件使用方法 Vmware 1.1.1  开启vmware 注: 同时只能开启一个VMware软件,如果开了两个VMware窗口 提示 ...

  2. sourse insight总是代码一写长了,就自动换行

    sourse insight总是代码一写长了,就自动换行. Document Options里面Word Wrap选项不勾选.

  3. Python基础(闭包函数、装饰器、模块和包)

    闭包函数 格式: def 函数名1(): def 函数名2(): 变量 = 值 return 变量 return 函数名2 func = 函数名1() key = func()

  4. App性能测试前需要了解的内存原理

    这两天在研究性能中内存方面的一块,网上也零散看了挺多文章,写得很细但是感觉不够整体,所以这篇算是总结一下吧,当个复习资料. 那么这里个人分为两个大部分,第一部分应用内的内存管理,主要是oom的理解,G ...

  5. 【HttpRunner v3.x】笔记 ——4. 测试用例-结构解析

    一.官方首推pytest格式 上篇文章我们知道了,httprunner可以支持三种格式的用例,分别是pytest.yaml和json.yaml和json是以前的版本所使用的用例格式,但是在3.x版本上 ...

  6. Stack (30)(模拟栈,输出中间数用set)

    Stack is one of the most fundamental data structures, which is based on the principle of Last In Fir ...

  7. 前端code导入excel

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 聊聊redis单线程为什么能做到高性能和io多路复用到底是个什么鬼

    1:io多路复用epoll  io多路复用简单来说就是一个线程处理多个网络请求 我们知道epoll in 的事件触发是可读了,这个比较好理解,比如一个连接过来,或者一个数据发送过来了,那么in事件就触 ...

  9. 简单说说TCP三次握手、四次挥手机制

    1.什么是TCP TCP全称Transmission Control Protocol(传输控制协议),是一种面向连接的.可靠的.基于字节流的传输层通信协议.是为了在不可靠的互联网络上提供可靠的端到端 ...

  10. 跟着尚硅谷系统学习Docker-【day04】

    day04-20200716   p18.docker容器数据卷   docker容器中的数据,做持久化. 容器关闭以后容器内的数据就没有了. 保存到数据库或者服务器宿主机里面.   作用:容器间可以 ...