KMP-子串匹配算法-關鍵點理解

1.理解next[]數組的使用與來歷

2.求解next[]數組

一、kmp算法的原理

? ? ? ? 首先觀察暴力解法:假設主串為:abdxxabc,模式串為abxxabd。

暴力解法,就是對主串每個字符作為第一個字符,開始和模式串比較。

比如:從主串第一個字符a開始,比較到d發現不相等,然后從第二個字符b開始,直接不相等。以此類推,直到匹配或者到主串末尾。

? ? ? ? ? ?abxabc|abxabd? ? ? ????????????????????????abxabc|abxabd? ? ?...? ? ? ?abxabc|abxabd

? ? ? ? ? ?abxabd? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?abxabd? ? ? ? ? ? ? ??...? ? ? ? ? ? ? ? ? ? abxabd

? ? ? ? ? ? ?圖一? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? 圖二? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖三

比較操作的時間復雜度為O(m×n)。

kmp算法在此基礎上進行改進,關鍵點為,利用已經比較過的部分,比如圖一的abxabd。

? ? ? ? 當遇見不匹配的情況時,通過模式串的最長相等前后綴來確定下一次模式串比較的位置,并且不需要回退主串和模式串。前綴為不包含最后一個字符,包含第一個字符的子串,后綴為不包含第一個字符,保護最后一個字符的字串。

? ? ? ? 理解:匹配過程中,不匹配的情形只有兩種情況,其實也可以看成一種情況。第一種情況:第一個字符就不匹配,也就是說不匹配的字符前面沒有字符。如圖二。第二種情況:第n個字符不匹配,前n-1個字符匹配。如圖一。

? ? ? ?第一種情況由于第一個字符就不匹配,所以主串直接遍歷下一個字符,模式串還是第一個字符開始比較。第二種情況:如圖一,abxab是匹配的,此時,我們只需要檢查abxab這個字符串的最長相等前后綴的長度,最長相等前后綴為ab,長度為2。下一次我們直接比較模式串下標為2的字符x和此時主串不相等的字符c。然后重復上面的比較操作。

? ? ? ? 關鍵點是理解最長相等前后綴的性質。在已經匹配的字符串中,如何最長相等前后綴為0,也即是沒有相等的前后綴,那么顯然,由于已經匹配的字符串在模式串中為模式串的一個前綴,而在主串中為已經遍歷過的匹配的字符串的后綴,假設從i開始比較,到j不相等,主串i ~ j-1這一部分是模式串的一個前綴,因為肯定是從模式串的第一個字符開始比較的。而i - j-1這一部分如果沒有相等的前后綴,那么顯然不可能有和模式串匹配的部分,因為i~j-1是模式串的一個前綴,你都沒有后綴等于前綴,所以主串不用回退,直接遍歷下一個字符;如果有相等的前后綴,我們取最長的相等前后綴,i~j-1是模式串的一個前綴,假設最長的相等前后綴長度為2,也就是i, i+1是等于j-2, j-1,所以模式串的下一次比較的位置就是i+2,因為i~j-1也是主串的一部分,主串下一次比較的開始字符是j。

2.關鍵的最長相等前后綴的求解,也就是常說的next的數組。也就是前綴表。

一、暴力求解:兩個指針,left,right,分別指向后綴的開始,前綴的末尾。從最長的前后綴字串開始比較,逐漸縮短,直到不相等。

二、常用解法:kmp的思路,其實求解next數組的過程中也用到了kmp的算法思想。一個指針j,表示以i-1為尾部的前綴字符串的最長相等前后綴的長度,也即是j指向最長相等前綴的下一個字符。i遍歷字符串,從0開始。顯然,第一個前綴,最長相等前后綴長度為0。

比如字符串abcxabxabcxx。next[]數組:next[0]:前綴a的最長相等前后綴的長度;next[1]:前綴ab的最長相等前后綴的長度;next[2]:前綴abc的最長相等前后綴的長度,....表示以i結尾的前綴字符串的最長相等前后綴的長度。

for(i = 0; i < str.size(); ++i)遍歷一個一個求next[i]數組。

if (str[i] == str[j])? ?next[i] = ++j;

abcxabxabcxx: 假設此時i遍歷到了x,j為i-1結尾的前綴字符串的最長相等前后綴長度,也就是紅色部分表示的前綴字符串的最長相等前后綴長度,為2,也即是j指向最長相等前綴的下一個字符c。

其實就是next[i]是和next[i-1]有關系的。

關鍵是str[i] != str[j], while(j > 0 && str[i] != str[j]) j = next[j-1];其實就是把字符串0~j看成模式串,

i-j~i看成主串,因為指針j,表示以i-1為尾部的前綴字符串的最長相等前后綴的長度,也即是j指向最長相等前綴的下一個字符。i-j~i-1是等于0-j-1的。

28. 找出字符串中第一個匹配項的下標 - 力扣(LeetCode)

參考代碼:

class Solution {
public:int strStr(string haystack, string needle) {//第一部分:求解next[]數組vector<int> next(needle.size());int j = 0;for(int i = 1; i < needle.size(); ++i){while(j > 0 && needle[j] != needle[i]){j = next[j - 1];}if(needle[i] == needle[j]){j++;}next[i] = j;}//第二部分:匹配文本串j = 0;for(int i = 0; i < haystack.size(); ++i){while(j > 0 && needle[j] != haystack[i])j = next[j - 1];if(haystack[i] == needle[j]){j++;}if(j == needle.size())return i - j + 1;}return -1;}
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/74024.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/74024.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/74024.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Flutter 學習之旅 之 flutter 使用 SQLite(sqflite) 實現簡單的數據本地化 保存/獲取/移除/判斷是否存在 的簡單封裝

Flutter 學習之旅 之 flutter 使用 SQLite&#xff08;sqflite&#xff09; 實現簡單的數據本地化 保存/獲取/移除/判斷是否存在 的簡單封裝 目錄 Flutter 學習之旅 之 flutter 使用 SQLite&#xff08;sqflite&#xff09; 實現簡單的數據本地化 保存/獲取/移除/判斷是否存在…

群體智能優化算法-粒子群優化算法(Particle Swarm Optimization, PSO,含Matlab源代碼)

摘要&#xff08;Abstract&#xff09; 粒子群優化&#xff08;PSO&#xff09;是一種基于群體智能的優化算法&#xff0c;受鳥群覓食行為的啟發。PSO 通過模擬粒子&#xff08;個體&#xff09;在搜索空間中的運動來尋找最優解。每個粒子根據自身的歷史最優位置&#xff08;p…

Redis 在windows下的下載安裝與配置

參考鏈接:https://developer.aliyun.com/article/1395346 下載 Redis 訪問 Redis 下載地址&#xff1a;https://github.com/tporadowski/redis/releases 下載 Redis 時&#xff0c;你可以選擇 ZIP 包或 MSI 安裝&#xff1a; ZIP包&#xff1a;需要手動解壓、初始化、配置和…

UE5材質法線強度控制節點FlattenNormal

連法 FlattenNormal內部是這樣的 FlattenNormal的作用是用來調整法線強度 連上FlattenNormal后 拉高數值

在 Elasticsearch 中探索基于 NVIDIA 的 GPU 加速向量搜索

作者&#xff1a;來自 Elastic Chris Hegarty 及 Hemant Malik 由 NVIDIA cuVS 提供支持&#xff0c;此次合作旨在為開發者在 Elasticsearch 中的向量搜索提供 GPU 加速。 在 Elastic Engineering 組織內&#xff0c;我們一直致力于優化向量數據庫的性能。我們的使命是讓 Lucen…

Android 13深度定制:SystemUI狀態欄時間居中顯示終極實戰指南

一、架構設計與技術解析 1. SystemUI狀態欄核心布局機制 層級結構 mermaid 復制 graph TDPhoneStatusBarView --> StatusBarContents[status_bar_contents]StatusBarContents --> LeftLayout[status_bar_left_side]StatusBarContents --> ClockLayout[Clock控件]Left…

ArcGIS10.X影像智能下載!遷移ArcGIS Pro批量智能高清影像下載工具至ArcGIS!

上周我們分享了 我寫的一個ArcGIS Pro版批量下載高清影像&#xff08;谷歌、天地圖、ESRI等&#xff09;工具給大家&#xff0c;Deepseek我&#xff01;寫一個ArcGIS Pro批量下載高清影像&#xff08;谷歌、天地圖、ESRI等&#xff09;工具給大家-CSDN博客文章瀏覽閱讀130次。深…

前端面經分享(25/03/19)

北京一家做協同辦公軟件出海的公司&#xff0c;技術一面&#xff0c;20k-40k&#xff0c;要求3-5年 詳細聊了一下上家公司的項目上家公司的項目是不做了嗎&#xff0c;離職原因是什么&#xff0c;你覺得公司的這個產品怎么樣在做AI類的業務時&#xff0c;作為前端感覺跟常規業務…

7 款可視化爬蟲工具全解析:案例示范與操作指南

目錄 1. ParseHub 2.WebHarvy 3.DataMiner 4.Dexi.io 5.ContentGrabber 6.Portia 7.UiPath 文檔聚焦 7 款熱門可視化爬蟲工具&#xff0c;突出簡便的可視化操作&#xff0c;簡單拖拽、設置&#xff0c;無需編程知識&#xff0c;人人皆可上手。 1. ParseHub ParseHub 是一…

使用 `pytest` 框架時,可以通過極限封裝將 YAML 文件的讀取、解析

在使用 pytest 框架時,可以通過極限封裝將 YAML 文件的讀取、解析和測試用例的通用邏輯封裝成共享的方法或 fixture,從而減少重復代碼。以下是詳細的實現步驟和示例。 1. 封裝 YAML 文件讀取和解析 將 YAML 文件的讀取和解析邏輯封裝到一個工具函數中,供所有測試用例調用。…

HarmonyOS next性能優化:多維度策略與實戰案例

HarmonyOS next性能優化&#xff1a;多維度策略與實戰案例 在HarmonyOS next開發中&#xff0c;性能優化是提升用戶體驗、確保應用流暢運行的關鍵。本文將從多個角度探討HarmonyOS next的性能優化策略&#xff0c;并通過示例代碼展示優化前后的效果對比&#xff0c;幫助開發者…

springboot項目,mapper.xml里面,jdbcType報錯 已解決

找了很多資料&#xff0c;最后發現原來是依賴版本不兼容的問題。改了版本號即可 報錯原因&#xff1a; springboot版本為2.16.3 但是我導入的依賴版本是3.0.1&#xff0c;不兼容&#xff0c;報錯 解決&#xff1a;修改版本號&#xff0c;2.3.1兼容springboot2.6.x。依賴下載完…

rust學習筆記16-206.反轉鏈表(遞歸)

rust函數遞歸在14中已經提到&#xff0c;接下來我們把206.反轉鏈表&#xff0c;用遞歸法實現 遞歸函數通常包含兩個主要部分&#xff1a; 基準條件&#xff08;Base Case&#xff09;&#xff1a;遞歸終止的條件&#xff0c;避免無限遞歸。 遞歸步驟&#xff08;Recursive Ste…

QT-LINUX-Bluetooth藍牙開發

BlueToothAPI QT-BlueToothApi Qt Bluetooth 6.8.2 官方提供的藍牙API不支持linux。 D-Bus的API實現藍牙 確保系統中安裝了 BlueZ(版本需≥5.56),并且 Qt 已正確安裝并配置了 D-Bus 支持。 默默看了下自己的版本.....D-BUS的API也不支持。 在 D-Bus 中,org 目錄是 D-Bus…

鴻蒙Next開發與未來發展的變革:全場景操作系統的全新紀元

文章目錄 引言&#xff1a;從兼容到自主的跨越式進化一、鴻蒙Next技術架構解析1.1 系統架構全景圖1.1.1 微內核架構優勢 1.2 與OpenHarmony的關系 二、開發范式革命2.1 應用開發模式對比2.1.1 元服務&#xff08;Meta Service&#xff09;定義 2.2 開發工具鏈升級&#xff08;D…

【docker】--- 詳解 WSL2 中的 Ubuntu 和 Docker Desktop 的區別和關系!

在編程的藝術世界里,代碼和靈感需要尋找到最佳的交融點,才能打造出令人為之驚嘆的作品。而在這座秋知葉i博客的殿堂里,我們將共同追尋這種完美結合,為未來的世界留下屬于我們的獨特印記。【WSL 】--- Windows11 遷移 WSL 超詳細指南 —— 給室友換一個宿舍! 開發環境一、引…

利用Python爬蟲獲取Shopee(蝦皮)商品詳情:實戰指南

在跨境電商領域&#xff0c;Shopee&#xff08;蝦皮&#xff09;作為東南亞及臺灣地區領先的電商平臺&#xff0c;擁有海量的商品信息。無論是進行市場調研、數據分析&#xff0c;還是尋找熱門商品&#xff0c;獲取Shopee商品詳情都是一項極具價值的任務。然而&#xff0c;手動…

【OCR】總結github上開源 OCR 工具:讓文字識別更簡單

前言 在數字化的時代&#xff0c;光學字符識別&#xff08;OCR&#xff09;技術成為了我們處理文檔、圖像文字信息的得力助手。它能夠將圖像中的文字信息轉換為可編輯和可處理的文本數據&#xff0c;極大地提高了信息處理的效率。今天&#xff0c;我要給大家介紹一些優秀的開源…

GenICam標準

GenICam的目標是為所有類型的相機提供一個統一的編程接口。無論相機使用的是哪種傳輸協議或實現了哪些功能&#xff0c;編程接口&#xff08;API&#xff09;都是一樣的。 GenICam&#xff08;Generic Interface for Cameras&#xff09;是一個為工業相機和圖像采集設備設計的…

Docker學習筆記(十)搭建Docker私有倉庫

一、環境配置 1、宿主機系統&#xff1a;macOS Sequoia(版本15.2) 2、虛擬機VMware Fusion版本&#xff1a;專業版 13.6.2 (24409261) 3、虛擬機系統&#xff1a;AlmaLinux-9-latest-x86_64-boot.iso 二、安裝Harbor開源企業級Docker鏡像 Harbor 是一個開源的企業級 Docker…