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.pswp.cn/news/445981.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445981.shtml
英文地址,請注明出處:http://en.pswp.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…