本文代码来自于中国大学MOOC

KMP课件下载

注释内容为自己理解,如有错误请评论,或者私信给我,谢谢

#include <stdio.h>
#include "stdlib.h"
#include "string.h" typedef int Position; Position KMP(char string[25], char pattern[7]); void BuildMatch(char *pattern, int *pInt); #define NotFound -1 int main() {
char string[] = "this is a simple example";
char pattern[] = "simple";
Position p = KMP(string, pattern);
if (p == NotFound) printf("Not found.\n");
else {
printf("%s\n", string + p);
printf("%f\n", p);
}
return 0;
} Position KMP(char *string, char *pattern) {
int n = strlen(string);
int m = strlen(pattern);
int s, p, *match; if (m > n) return NotFound;
match = (int *) malloc(sizeof(int) * m);
// 查询match最长匹配字符串位置值 例如:图1-1
// pattern a b c a b
// index 0 1 2 3 4
// match -1 -1 -1 0 1
BuildMatch(pattern, match); s = p = 0;
while (s < n && p < m) {
if (string[s] == pattern[p]) {
s++;
p++;
} else if (p > 0) {
// 将p置为 前p-1个元素 最大子串长度+1
// 如图1-2
p = match[p - 1] + 1;
} else
s++;
}
return (p == m) ? (s - m) : NotFound;
} void BuildMatch(char *pattern, int *match) {
int i, j;
int m = strlen(pattern);
match[0] = -1;// -1 表示子串长度不存在,无任何相同的元素
for (int j = 1; j < m; ++j) {
// i表示前j-1个元素最大相同子串长度 数组索引位置 index-length 0-1
i = match[j - 1]; while ((i >= 0) && (pattern[i + 1] != pattern[j]))
// 第j个下标的字符和(match[j-1]+1)下标上的元素比较
// 如果不匹配,则根据下标为match[j-1]的相同串基础上进行条件比较
// 因为match[j-1]已经存在,那么绿紫色整块和后面绿紫块肯定一样
// 又第一个小绿块为match[match[j-1]],绿块和紫块相同
// 所以第一个绿块和最后一个紫块相同,只需比较问号位置的值即可
// char[match[match[j-1]]+1] 和 char[j] 的值是否相等
// 如图 1-3
i = match[i]; if (pattern[i + 1] == pattern[j])
// 如图 1-4
match[j] = i + 1;
// 如果都匹配不上就直接设置为-1
else match[j] = -1;
}
}



match[j]的值实际上是前j个(包括j)元素的最大子串长度 对应到数组中的位置 比如图中 j = 6; 最大子串(abca)的长度为4,

在数组中的索引为3



当比较到后面不相等时,模式串相当于要后移到从上往下的第三个横条的情形,也就是把第二个横条情况p = match[p-1]+1

  • 第j个下标的字符和(match[j-1]+1)下标上的元素比较
  • 如果不匹配,则根据下标为match[j-1]的相同串基础上进行条件比较
  • 因为match[j-1]已经存在,那么绿紫色整块和后面绿紫块肯定一样
  • 又第一个小绿块为match[match[j-1]],绿块和紫块相同
  • 所以第一个绿块和最后一个紫块相同,只需比较问号位置的值即可
  • char[match[match[j-1]]+1]char[j] 的值是否相等

最新文章

  1. mysql函数大全
  2. [Android]解决ClickableSpan中点击后ListView中item的长按冲突的问题
  3. 获取DIV与浏览器顶部相聚一定位置之后移动DIV
  4. Python初学者笔记(4)-简单的通讯录
  5. highcharts联合jquery ajax 后端取数据
  6. call,apply,bind方法的总结
  7. C#中的Dictionary字典类介绍
  8. MVC3中 ViewBag、ViewData和TempData的使用和区别(不是自己写的)
  9. php测试题整理(0519)
  10. Lucene学习总结之七:Lucene搜索过程解析
  11. IOS开发 统计XCODE 代码行数
  12. 一个自定义python分布式专用爬虫框架。支持断点爬取和确保消息100%不丢失,哪怕是在爬取进行中随意关停和随意对电脑断电。
  13. MySQL误删数据
  14. Datatable数据转换成excel导出时 数值类型在EXCEL中为文本形式 无法进行统计
  15. Bootstrap学习记录-3.Badge、Breadcrumb、Buttons、 Button Group、Card、Carousel
  16. Ionic下的Jpush消息推送与内容显示
  17. ### The error may involve defaultParameterMap ### The error occurred while setting parameters
  18. [Big Data - ZooKeeper] ZooKeeper: A Distributed Coordination Service for Distributed Applications
  19. 搭建VUE项目
  20. 介绍 Scratch 3.0:扩展编码创造力

热门文章

  1. 攻防世界 reverse Windows_Reverse1
  2. C++单重继承分析
  3. 12、MyBatis教程之缓存
  4. 巧用 SVG 滤镜还能制作表情包?
  5. 常用Linux操作
  6. [Fundamental of Power Electronics]-PART II-9. 控制器设计-9.5 控制器的设计
  7. 配置动态刷新RefreshScope注解使用局限性(一)
  8. Manjaro 安装教程
  9. 配置Jupyter环境:安装+补全+美化+常用库
  10. Josephus问题的queue解法