算法介绍:

KMP是一种用来处理字符串匹配问题的算法,给你两个字符串A、B,让你回答B是否为A的子串,或者A中有多少子串等于B。

这题最暴力的做法是:枚举A中与B相等的子串的左端点,再判断是否与B相等,时间复杂度是O(nm)的,很慢。而我们要介绍的KMP算法的时间复杂度是理论上O(n+m)的,比他要快得多。

算法核心思路分析:

KMP算法其实是这么做的:两个指针,i,j,表示A中从i-j+1到i的这段子串与B的1到j完全相等。当A[i+1]=B[j+1]时显然两个指针都自增1即可。那么当A[i+1]<>B[j+1]时呢?我们就需要重新匹配j指针,找到能够与指针i+1相匹配的新也要是最大的的指针j,使得以上关系仍然成立(注意是重新匹配指针j,而i始终按照自己的进程不断地+1)。而我们应该如何重新匹配指针j呢?注意到字符串B中,会有子串1-x,为1-j的子串,而如果有A[i+1]<>B[j+1]但是A[i+1]=B[x+1]的话,我们便不用直接将指针j清零,只需要把j赋为x即可。

代码:

var
p:array[0..1000]of longint;
a,b:string;
i,j,lena,lenb,ans:longint;
begin
readln(a);
readln(b);
lena:=length(a); lenb:=length(b);
p[1]:=0; j:=0;
for i:=1 to lenb-1 do
begin
while (j>0)and(b[j+1]<>b[i+1]) do j:=p[j];
if b[j+1]=b[i+1] then inc(j);
p[i+1]:=j;
end;
j:=0;
for i:=0 to lena-1 do
begin
while (j>0)and(a[i+1]<>b[j+1]) do j:=p[j];
if b[j+1]=a[i+1] then inc(j);
if j=lenb then
begin
inc(ans);
j:=p[j];
end;
end;
writeln(ans);
end.

[KMP]字符串匹配算法的更多相关文章

  1. BM和KMP字符串匹配算法学习

    BM和KMP字符串匹配算法学习 分类: 研究与学习 字符串匹配BM(Boyer-Moore)算法学习心得 http://www.cnblogs.com/a180285/archive/2011/12/ ...

  2. KMP字符串匹配算法理解(转)

    一.引言 主串(被扫描的串):S='s0s1...sn-1',i 为主串下标指针,指示每回合匹配过程中主串的当前被比较字符: 模式串(需要在主串中寻找的串):P='p0p1...pm-1',j 为模式 ...

  3. 【KMP】【字符串】KMP字符串匹配算法 学习笔记

    一.简介     KMP是由Knuth.Morris和Prat发明的字符串匹配算法,它的时间复杂度是均摊\(O(n+m)\).其实用Hash也可以做到线性,只不过Hash存在极其微小的难以避免的冲突. ...

  4. KMP字符串匹配算法翔解❤

    看了Angel_Kitty学姐的博客,我豁然开朗,写下此文: 那么首先我们知道,kmp算法是一种字符串匹配算法,那么我们来看一个例子. 比方说,现在我有两段像这样子的字符串: 分别是T和P,很明显,P ...

  5. 每周一算法之六——KMP字符串匹配算法

    KMP是一种著名的字符串模式匹配算法,它的名称来自三个发明人的名字.这个算法的一个特点就是,在匹配时,主串的指针不用回溯,整个匹配过程中,只需要对主串扫描一遍就可以了.因此适合对大字符串进行匹配. 搜 ...

  6. 保证你能看懂的KMP字符串匹配算法

    文章转载自一位大牛: 阮一峰原网址http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm ...

  7. 子字符串substring 问题 - KMP 字符串匹配算法备忘录

    本文为自己对KMP的理解. 对KMP很好的介绍可以参考 http://www.cnblogs.com/yjiyjige/p/3263858.html 本文为对这篇文章的提炼和补充. KMP算法基本思想 ...

  8. KMP字符串匹配算法详解

    KMP算法利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息.时间复杂度O(m+n). Next()函数 ...

  9. KMP字符串匹配算法

    static void Main(string[] args) { var d = KMP("abcabcadabc55abcabcadabc55", "abcabcad ...

随机推荐

  1. 太刺激了,面试官让我手写跳表,而我用两种实现方式吊打了TA!

    前言 本文收录于专辑:http://dwz.win/HjK,点击解锁更多数据结构与算法的知识. 你好,我是彤哥. 上一节,我们一起学习了关于跳表的理论知识,相信通过上一节的学习,你一定可以给面试官完完 ...

  2. 渣渣的Leetcode之旅(Python3)_1.两数之和

    题目:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标.你可以假设每种输入只会对应一个答案.但是,数组中同一个元素不能使用两遍 ...

  3. django之admin配置

    要在admin内显示的表,在admin中进行注册,然后在登录admin后台,才可以对表进行操作例如:from django.contrib import adminfrom app01 import ...

  4. Spring boot中配置HikariCP连接池

    # jdbc_config datasourcespring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasourc ...

  5. Java虚拟机栈--栈帧

    栈帧的内部结构 每个栈帧中存储着 1.局部变量表(Local Variables) 2.操作数栈(Operand Stack)(或表达式栈) 3.动态链接(Dynamic Linking)(或执行&q ...

  6. Github上如何添加 LICENSE 文件?

    什么是开源软件? 开源软件是所有人都可以修改和补充的软件,因为开源软件的 license 协议允许这样做. Git版本控制系统就是开源的软件. 实际上开源软件的一个重要组成部分就是添加 license ...

  7. yum管理——linux字符界面安装图形化及两种界面的切换(3)

    1.查看yum软件包组 yum groups list 2.选择安装带 GUI 的服务器 yum groups install "带 GUI 的服务器" 3.字符界面切换为图形化界 ...

  8. web网站——nginx,LNMP部署03

    nginx功能: (1)web服务器: 默认网页目录为:/usr/share/nginx/html (2)反向代理服务器: nginx代替客户端访问后端服务器,后端服务器只知道是nginx的请求,并将 ...

  9. chrome插件: yapi 接口TypeScript代码生成器

    前言 2020-09-12 天气晴,蓝天白云,微风,甚好. 前端Jser一枚,在公司的电脑前,浏览器打开着yapi的接口文档,那密密麻麻的接口数据,要一个一个的去敲打成为TypeScript的inte ...

  10. swagger2注解详细说明

    @Api:用在请求的类上,表示对类的说明 tags="说明该类的作用,可以在UI界面上看到的注解" value="该参数没什么意义,在UI界面上也看到,所以不需要配置&q ...