python 求子字符串_(6)KMP算法(求子串的位置)______字符串的匹配

问题:

已知字符串 B 是字符串 A 的一个子串,问字符串 B 在字符串 A 的第一次出现位置.

暴力方法:从 A 字符串 的每个位置开始对字符串 B 进行匹配. 这种方法根据数据的不同 复杂度不同最高可以达到O( m*n ). (m,n分别为两个字符串的长度)

KMP算法:

我们先来看普通的暴力方法在对下面的匹配过程:

这个匹配过程到达 X,Y 处发现不匹配,按照暴力方法我们就把下面的字符串向右移动一个字符然后继续跟A进行匹配.但是实际上看图我们就可以知道移动一个字符肯定还是无法匹配成功, 而这样的一步一步的移动也是十分费时.那么我们就要找到最佳的右移长度.

看这幅图:

假如在匹配d和b的时候失败了,我们移动 a 到 A  对应的位置 , 那么就要满足 AB 段和 ab段匹配 ,又因为 cd 和 AB 段已经匹配上了, 实际上就是要 ab 段和 cd 段匹配.我们要移动最长距离就要保证 ab  和 cd 在匹配上的同时, ab 串的长度最大值.那么就可以直接把 a 移动到 A 进行匹配.换句话就是求 下面那个字符串在 ad 段部分的首尾匹配子串的最大长度.

这个时候我们引入一个数组 c [ i ]  表示 下面的待匹配的子串在 0 ~ i-1 部分的首尾匹配子串的最大长度.初始化前面两个为0.

然后上下开始匹配,匹配到 b 的时候我们先计算下面数组的值,计算方法是看前一个位置的数组的值,这里 b 的前面一个位置的值是0,那么就比较前一字符与0位置字符是否相等.如果相等,当前数组值就等于前一数组的值加1,如果不相等当前数组值就等于0.

现在我们就递推到b 发现  b 前面的字符和 0字符相同都为 A 那么  b 下面对应的数组的值为 0+1=1;

继续递推,到 A  ,前一数组的值 为 1 , 那么我们比较前一字符与 1 位置的字符 一个是 b ,一个是 A.那么 A对应下面的数组值为 0;

继续递推到 A ,前一数组的值为 0 , 那么我们比较前一字符与 0 位置的字符, 两个都是A 那么 当前A下面对应的数组值为0+1=1

继续匹配……

直到算完 Y 下面的数组的值后发现 上下不匹配, 我们找 Y下面的值 4, 然后从 4 号 位置的字符 与上面字符串的 X进行匹配,如果相同就继续重复以上操作.如果不相同那么继续调用4 号位置的字符下面的数组的值 0 ,然后用 0位置的元素和 X 比较.相同继续向后匹配,如果不同就继续调用下面的数组………………(注意:如果0

位置的字符也无法匹配 X 那么不用调用0号位置字符下面的数组的值,而是继续用0号位置的字符比较上面 X 后面的一个字符……)

结束:如果下面的字符串的最后一个字符也匹配成功那么, 上面字符串的匹配成功的最后一个字符位置减去下面字符串的长度再加1 就是下面字符串出现在上面字符串的第一次位置.

代码:

#include

#include

char str1[100],str2[10]; //str2是str1的子串.

int k,c[10],ans;

void kmp(int t1,int t2)

{

if(str2[t2]=='\0'){ //先判断是否匹配完

ans=t1-t2;

return;

}

if(t2>1&&c[t2]==-1){ //继续计算当前字符下面的数组的值.

if(str2[t2-1]==str2[c[t2-1]]) c[t2]=c[t2-1]+1;

else c[t2]=0;

}

if(str1[t1]==str2[t2]) // 如果当前字符匹配成功,继续向后匹配.

kmp(t1+1,t2+1);

else if(t2==0) // 如果当前字符匹配失败,但是下面的字符位置是0,那么上面字符向后移动一个继续匹配.

kmp(t1+1,t2);

else // 如果当前字符匹配失败,但是下面字符的位置不是0,那么调用当前字符下面c数组的值进行匹配

kmp(t1,c[t2]);

}

int main()

{

while(scanf("%s%s",str1,str2)!=EOF){

memset(c,-1,sizeof(c));

c[0]=c[1]=0; //初始化c数组.

kmp(0,0);

printf("%d\n",ans+1);

}

return 0;

}

时间复杂度在 O(n)~O(n+m) 之间,  注意:n 为 str1 的长度

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445981.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用Python将多张图片合并成一PDF文件

先前条件 需要安装两模块:fpdf、PIL pip install fpdfpip install PIL 放码过来 from fpdf import FPDF from PIL import Image import osdef makePdf(pdfFileName, listPages):cover Image.open(listPages[0])width, height cover.sizepdf FPDF(unit "…

FFmpeg源代码简单分析-通用-结构体分析-关键结构体之间的关系

参考链接 FFMPEG中最关键的结构体之间的关系_雷霄骅的博客-CSDN博客_ffmpeg 结构体关系 最关键的结构体可以分成以下几类: 解协议(http,rtsp,rtmp,mms) AVIOContext,URLProtocol,URLContext主要存储视音频使用的协…

用Python下载文件

前提条件 需要事先安装requests模块: pip install requests 放码过来 import requestsurl XXX #文件下载来源URL filename #下载到本地后新文件名 r requests.get(url) with open(filename, "wb") as code:code.write(r.content)实战演习 从目标…

distenct oracle_Oracle的distinct关键字

distinct关键字用于从查询的结果集中筛选出唯一值的记录。我们通过示例来介绍distinct关键字的用法。一、生成测试数据用以下SQL创建超女基本信息表(T_GIRL),插入一些测试数据。create table T_GIRL(id char(4) not null, -- 编号name varchar2(30) not null, -- 姓…

FFmpeg源代码简单分析-通用-常见结构体的初始化和销毁(AVFormatContext,AVFrame等)

参考链接 FFmpeg源代码简单分析:常见结构体的初始化和销毁(AVFormatContext,AVFrame等)_雷霄骅的博客-CSDN博客 结构体 AVFormatContext:统领全局的基本结构体。主要用于处理封装格式(FLV/MKV/RMVB等&…

python中object转为float_object格式怎样无损转换成float64格式

这次给大家带来object格式怎样无损转换成float64格式,object格式无损转换成float64格式的注意事项有哪些,下面就是实战案例,一起来看一下。在数据处理过程中比如从CSV文件中导入数据data_df pd.read_csv("names.csv")在处理之前一…

FFmpeg源代码简单分析-通用-avio_open2()

参考链接 FFmpeg源代码简单分析:avio_open2()_雷霄骅的博客-CSDN博客_avio_open avio_open2() 该函数用于打开FFmpeg的输入输出文件avio_open2()的声明位于libavformat\avio.h文件中,如下所示。 /*** Create and initialize a AVIOContext for accessi…

用Tomcat构建一个简单图片服务器

前提条件 Tomcat 7.0.90 方法一&#xff1a;修改配置文件 在TOMCAT_HOME/conf/server.xml配置文件内的<Host>内添加一子标签&#xff1a; <Context docBase"C:\exambase\" path"/img"/>方法二&#xff1a;添加Servlet 新建一应用&#xf…

flash静态的农夫走路_健身神动作——你不知道的“农夫行走”

原标题&#xff1a;健身神动作——你不知道的“农夫行走”本期导读握力是训练中及其重要的一环&#xff0c;强大的握力会使你的训练效果MAX&#xff0c;就像开了加速器一样&#xff01;很多人把握力和前臂力量混为一谈&#xff0c;主要使用腕弯举提高握力。实际上&#xff0c;握…

FFmpeg源代码简单分析-通用-av_find_decoder()和av_find_encoder()

参考链接 FFmpeg源代码简单分析&#xff1a;av_find_decoder()和av_find_encoder()_雷霄骅的博客-CSDN博客_avcodec_find_encoder avcodec_find_encoder avcodec_find_encoder()用于查找FFmpeg的编码器avcodec_find_encoder()的声明位于libavcodec\codec.h 版本差异avcode…

用Java的Set实现交并差等集合运算

放码过来 package com.lun.util;import java.util.HashSet; import java.util.Set;public class SetUtils {public static <T> Set<T> union(Set<T> setA, Set<T> setB) {Set<T> tmp new HashSet<T>(setA);tmp.addAll(setB);return tmp;…

post方法就反回了一个string字符串前台怎么接_Golang Web入门(2):如何实现一个RESTful风格的路由...

摘要在上一篇文章中&#xff0c;我们聊了聊在Golang中怎么实现一个Http服务器。但是在最后我们可以发现&#xff0c;固然DefaultServeMux可以做路由分发的功能&#xff0c;但是他的功能同样是不完善的。由DefaultServeMux做路由分发&#xff0c;是不能实现RESTful风格的API的&a…

FFmpeg源代码简单分析-通用-avcodec_open2()

参考链接 FFmpeg源代码简单分析&#xff1a;avcodec_open2()_雷霄骅的博客-CSDN博客 avcodec_open2() 该函数用于初始化一个音视频编解码器的AVCodecContextavcodec_open2()的声明位于libavcodec\avcodec.h&#xff0c;如下所示。 /*** Initialize the AVCodecContext to use…

统计MySQL中某数据库硬盘占用量大小

放码过来 select TABLE_NAME, concat(truncate(data_length/1024/1024,2), MB) as data_size, concat(truncate(index_length/1024/1024,2), MB) as index_size from information_schema.tables where TABLE_SCHEMA your_db_name order by data_length desc;运行结果 参考…

halcon 相似度_Halcon分类函数,shape模型

《zw版Halcon-delphi系列原创教程》 Halcon分类函数013,shape模型为方便阅读&#xff0c;在不影响说明的前提下&#xff0c;笔者对函数进行了简化&#xff1a;:: 用符号“**”&#xff0c;替换&#xff1a;“procedure”:: 用大写字母“X”&#xff0c;替换&#xff1a;“IHUnt…

用Python将文件夹打包成Zip并备份至U盘

需求概要 将maven工程打包并备份至U盘。为了简单起见&#xff0c;只需备份工程中的src文件夹和pom.xml文件即可。 放码过来 import os import zipfile import datetime import shutilnowTimeStr datetime.datetime.now().strftime("%Y%m%d%H%M") newZipFileName …

FFmpeg源代码简单分析-通用-avcodec_close()

参考链接 FFmpeg源代码简单分析&#xff1a;avcodec_close()_雷霄骅的博客-CSDN博客_avcodec_close avcodec_close() 该函数用于关闭编码器avcodec_close()函数的声明位于libavcodec\avcodec.h&#xff0c;如下所示。 ​该函数只有一个参数&#xff0c;就是需要关闭的编码器的…

redis 缓存过期默认时间_redis缓存过期机制

笔者在线上使用redis缓存的时候发现即使某些查询已经设置了无过期时间的缓存,但是查询仍然非常耗时。经过排查,发现缓存确实已经不存在,导致了缓存击穿,查询直接访问了mysql数据库。因为我们用的是公司公共的redis缓存服务器,在和运维人员交流后发现可能是redis的内存淘汰…

FFmpeg源代码简单分析-解码-打开媒体的函数avformat_open_input

参考链接 图解FFMPEG打开媒体的函数avformat_open_input_雷霄骅的博客-CSDN博客_avformat_open_input 使用FFmpeg源代码简单分析&#xff1a;avformat_open_input()_雷霄骅的博客-CSDN博客_avformat_open_input() avformat_open_input FFmpeg打开媒体的的过程开始于avformat_…

redis session java获取attribute_面试题:给我说说你能想到几种分布式session实现?...

作者&#xff1a;yanglbme 来源&#xff1a;https://github.com/doocs/advanced-java/blob/master/docs/distributed-system/distributed-session.md# 面试官心理分析面试官问了你一堆 dubbo 是怎么玩儿的&#xff0c;你会玩儿 dubbo 就可以把单块系统弄成分布式系统&#xff0…