字符串匹配——煩人的KMP

? ? ? ? 相信很多同學看到這篇文章的時候,已經被KMP拿捏了吧!KMP算法說難,倒也不是很難,手算都會,說不難吧,短短幾行代碼愣是看不懂,輾轉反側,翻書查閱,視頻講解,最后還是一頭霧水,百思不得其解(俺也一樣.jpg),去年準備初試的時候,學到這里覺得這個算法很神奇,就想搞懂它,但是想了好幾天都不太理解,考試也不考代碼,就暫且擱置了,奈何復試要上機,故打開力扣刷刷題,開篇就看到KMP,又喚起了我那該死的記憶,昨晚冥思苦想一個半小時,終于悟出正道,來跟大家分享分享……(好久沒更博客了,有點話癆)

????????還不會手動模擬的同學,可以先去學習一下它的原理,我覺得王道咸魚學長這個講得不錯4.2_2_KMP算法(舊版上)_嗶哩嗶哩_bilibili。接下來,完成這道題,就一起反向拿捏這個煩人的KMP吧!


轉自力扣

找出字符串中第一個匹配項的下標

給你兩個字符串?haystack?和?needle?,請你在?haystack?字符串中找出?needle?字符串的第一個匹配項的下標(下標從 0 開始)。如果?needle?不是?haystack?的一部分,則返回??-1?

示例 1:

輸入:haystack = "sadbutsad", needle = "sad"
輸出:0
解釋:"sad" 在下標 0 和 6 處匹配。
第一個匹配項的下標是 0 ,所以返回 0 。

示例 2:

輸入:haystack = "leetcode", needle = "leeto"
輸出:-1
解釋:"leeto" 沒有在 "leetcode" 中出現,所以返回 -1 。
提示:1 <= haystack.length, needle.length <= 104haystack和?needle僅由小寫英文字符組成?????

理解next數組:

先舉個例子理解一下:模式串為ababaa,手算可得出其next數組為:011234,next數組執行如下:

從圖中可發現,每次回溯,前面都是有相同匹配的子串,本身匹不匹配不重要(我之前理解是,本身也要匹配,例如,第四位的b回溯到第二位的b,第四位的b前面是aba,第二位的b前面是a,有重復的子串a;第六位的a回溯到第四位的b,第六位的a前面是ababa,第四位的b前面是aba,有重復的子串aba,但a和b并不相等;再來看代碼,

void getNext(int next[], string s)
{next[0]=-1;int i=0, j=-1;while(i<s.length()){if(j==-1||s[i]==s[j])//前面都匹配{i++;j++;next[i]=j;}else{j=next[j];}}
}

大家可以想象一下這個場景,拿兩個相同的串進行匹配,一前一后,相差一個位置,如果相同,說明到目前為止我都是跟你相同的,而i++、j++,使得 i 指針和 j 指針之前都是相同的(準確的來說是有相同子串),則next[ i ] = j,表示當 i 不匹配的時候,可以跳到 j。如果這兩個指針所指的不相等,說明 i 指針和 j 指針之前也是相同的,但是 i 指針和 j 指針失配了,只能讓 j = next[ j ],讓 j 回溯,j 去找跟它前面相同的,讓 i 指針重新和新的 j 指針匹對;重復以上工作……


理解nextval數組:

這個就比next數組容易理解多了,還是拿上面的例子:模式串為ababaa,next數組為:011234,nextval數組為:010104;

例如,當第三位的a失配時,根據next數組要回溯到第一位的a,但是當第三位的a失配時,說明該元素不可能是a,回溯到第一位的a匹配則是多余操作,可以直接跳到它的next;當第六位的a失配時,根據next數組要回溯到第四位的b,因為a失配,只能說明該元素不是a,并不知道它是不是b,所以還要進行匹對;

代碼如下:(應該不難理解)

void getNextval(int nextval[], int next[], string s)
{nextval[0]=-1;for(int i=1; i<s.length(); i++){if(s[i]==s[next[i]])//該元素等于next里面的元素,因為字符串的首索引是0{nextval[i]=nextval[next[i]];}else{nextval[i]=next[i];}}
}

最后附上本題的ac代碼:

class Solution {
public:int strStr(string haystack, string needle){int next[10007]={0}, nextval[10007]={0};getNext(next, needle);getNextval(nextval, next, needle);int i=-1, j=-1;//i是主串,j是模式串int flag=0;//記錄是否匹配模式串while(1){if(j==-1||haystack[i]==needle[j]){i++;j++;}else{j=nextval[j];}if(j==needle.length())//匹配成功{flag=i-needle.length();return flag;}if(i==haystack.length())return -1;}}void getNext(int next[], string s){next[0]=-1;int i=0, j=-1;while(i<s.length()){if(j==-1||s[i]==s[j])//前面都匹配{i++;j++;next[i]=j;}else{j=next[j];}}}void getNextval(int nextval[], int next[], string s){nextval[0]=-1;for(int i=1; i<s.length(); i++){if(s[i]==s[next[i]])//該元素等于next里面的元素,因為字符串的首索引是0{nextval[i]=nextval[next[i]];}else{nextval[i]=next[i];}}}
};

可能大家還有一點疑惑:為什么我的下標是從-1開始,因為字符串的首字符下標是0,而書上的那些例題講解都是用字符數組存儲字符串,它的首字符下標是從1開始。

建議看懂理解了的同學去力扣重新做一下這道題,加深印象。希望能幫助到大家,歡迎指正!

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

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

相關文章

MySQL性能提升之道:深入探討SQL與索引優化實戰技巧

MySQL性能優化&#xff1a; MySQL性能優化是一個涉及多個層面的過程&#xff0c;旨在提高數據庫的響應速度、處理能力和資源利用率。以下是一些關鍵的性能優化策略&#xff1a; 硬件優化&#xff1a; 升級硬件資源&#xff0c;如CPU、內存、SSD硬盤等&#xff0c;以提供更好的…

electron nsis 安裝包 window下任務欄無法正常固定與取消固定 Pin to taskbar

問題 win10系統下&#xff0c;程序任務欄在固定后取消固定&#xff0c;展示的程序內容異常。 排查 1.通過論壇查詢&#xff0c;應該是與app的api setAppUserModelId 相關 https://github.com/electron/electron/issues/3303 2.electron-builder腳本 electron-builder…

三、低代碼平臺-單據配置(單表增刪改查)

一、業務效果圖 主界面 二、配置過程簡介 配置流程&#xff1a;業務表設計 -》業務對象建立-》業務單據配置-》菜單配置。 a、業務表設計 b、業務對象建立 c、業務單據配置 功能路徑&#xff1a;低代碼開發平臺/業務開發配置/單據配置維護 d、菜單配置

linux-tar命令--exclude

命令如下&#xff1a;將workscript 壓縮成workscript_v2.tar.gz&#xff0c;不打包workscript_v2目錄下的logs下的所有文件。 tar -zcf workscript_v2.tar.gz workscript --excludeworkscript_v2/logs workscript_v2.tar.gz--壓縮的文件名&#xff0c;可自定義 workscript--…

GCN原理回顧論文導讀

Cora_dataset description Cora數據集是一個常用的學術文獻用網絡數據集&#xff0c;用于研究學術文獻分類和圖網絡分析等任務。 該數據集由機器學習領域的博士論文摘要組成&#xff0c;共計2708篇論文&#xff0c;涵蓋了7個不同的學科領域。每篇論文都有一個唯一的ID&#xf…

【Linux】linux內核模塊編譯makefile

1、編譯進內核的模塊 如果需要將foo.ko編譯進內核&#xff0c;需要在makefile中進行配置&#xff1a; obj-y foo.o2、編譯可加載的模塊 如果需要將foo.ko編譯成可加載模塊&#xff0c;需要在makefile中進行配置&#xff1a; obj-m foo.oobj-m表示編譯生成可加載模塊。相對…

jQuery詳細介紹

一、引言 在Web開發的歷史長河中&#xff0c;JavaScript一直扮演著至關重要的角色。然而&#xff0c;原生的JavaScript在某些方面存在不足&#xff0c;如瀏覽器兼容性、DOM操作繁瑣等。為了簡化這些問題&#xff0c;jQuery應運而生。jQuery是一個輕量級的、功能豐富的JavaScri…

李沐動手學習深度學習——3.5練習

減少batch_size&#xff08;如減少到1&#xff09;是否會影響讀取性能&#xff1f; 肯定會影響&#xff0c;計算機io性能而言&#xff0c;隨著batch_size增大&#xff0c;讀取越來越快&#xff0c;需要的時間越少。這里會涉及到計算機操作系統的知識點&#xff0c;內存與硬盤之…

AmzTrends x TiDB Serverless:通過云原生改造實現全局成本降低 80%

本文介紹了廈門笛卡爾數據&#xff08;AmzTrends&#xff09;在面臨數據存儲挑戰時&#xff0c;選擇將其數據分析服務遷移到 TiDB Serverless 的思路和實踐。通過全托管的數據庫服務&#xff0c;AmzTrends 實現了全局成本降低 80% 的效果&#xff0c;同時也充分展示了 TiDB Ser…

redis一些概念知識

一、redis是什么 Redis是一種非關系型數據庫&#xff08;NoSQL&#xff09;&#xff0c;它主要以鍵值對存儲數據。與傳統的關系型數據庫相比&#xff0c;Redis更注重內存操作和高性能&#xff0c;常被用作緩存系統或分布式存儲系統。 以簡單的比喻來解釋Redis&#xff0c;可以…

kafka進階(二)

文章目錄 前言一、Ack機制二、ISR集合總結 前言 本篇主要介紹kafka 的 Ack機制 和 ISR集合 一、Ack機制 Kafka提供了三種不同的應答機制&#xff08;ACK&#xff09;&#xff1a; acks0&#xff1a;這是最不可靠的模式。在這種模式下&#xff0c;生產者不會等待來自服務器的…

三、軟考-系統架構設計師筆記-計算機系統基礎知識

計算機系統概述 計算機系統是指用于數據管理的計算機硬件、軟件及網絡組成的系統。 它是按人的要求接收和存儲信息&#xff0c;自動進行數據處理和計算&#xff0c;并輸出結果信息的機器系統。 馮諾依曼體系計算機結構&#xff1a; 1、計算機硬件組成 馮諾依曼計算機結構將…

正向代理的反爬蟲與防DDoS攻擊:保護網站免受惡意行為

目錄 前言 一、正向代理的原理 二、正向代理的反爬蟲功能 1. IP地址隱藏 2. 請求多樣化 三、正向代理的防DDoS攻擊功能 1. 均衡負載 2. IP過濾 結論 前言 在當前互聯網環境下&#xff0c;網站常常受到各種惡意行為的侵襲&#xff0c;其中包括爬蟲和DDoS攻擊。這些行為…

#WEB前端(DIV、SPAN)

1.實驗&#xff1a;DIV、SPAN 2.IDE&#xff1a;VSCODE 3.記錄&#xff1a; 類? 4.代碼&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdev…

《中國計算機學會通訊》2022年第10期讀書筆記

試看&#xff1a;https://dl.ccf.org.cn/reading.html?_ack1&id6177027364096000 為計算機科學技術的大變局立言 重要的不是找答案&#xff0c;而是提出別人沒有想到或者還不重視的科學問題和技術方向。 幾乎沒有人愿意去去急需研發人才的中小企業。 CCCF應當關心作為…

數據庫系統架構與DBMS功能探微:現代信息時代數據管理的關鍵

?? 歡迎大家來訪Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭?&#xff5e;?? &#x1f31f;&#x1f31f; 歡迎各位親愛的讀者&#xff0c;感謝你們抽出寶貴的時間來閱讀我的文章。 我是Srlua&#xff0c;在這里我會分享我的知識和經驗。&#x…

現代化數據架構升級:毫末智行自動駕駛如何應對年增20PB的數據規模挑戰?-OceanBase案例

毫末智行是一家致力于自動駕駛的人工智能技術公司&#xff0c;其前身是長城汽車智能駕駛前瞻分部&#xff0c;以零事故、零擁堵、自由出行和高效物流為目標&#xff0c;助力合作伙伴重塑和全面升級整個社會的出行及物流方式。 在自動駕駛領域中&#xff0c;是什么原因讓毫末智行…

Linux——基本指令

系列文章目錄 文章目錄 系列文章目錄一、Linux基本常識二、Linux基本指令2.1 mkdir指令&#xff08;重要&#xff09;2.2 rmdir指令2.3 rm指令&#xff08;重要&#xff09;2.4 touch指令2.5 ls指令2.6 pwd指令2.7 cd指令2.7.1 Linux中的目錄結構2.7.2 絕對路徑和相對路徑2.7.3…

對程序、進程、線程、并發、并行、高并發概念的講解

一、概述 程序、進程、線程、并發、并行和高并發是計算機科學領域中非常重要的概念。 了解進程、線程、并發和并行的概念&#xff0c;可以更好地利用計算機的多核處理器和并行計算能力&#xff0c;提高計算機性能。 了解進程和線程為操作系統中的資源管理提供了基礎&#xff…

【風格遷移】對比度保持連貫性損失 CCPL:解決圖像局部失真、視頻幀間的連貫性和閃爍

對比度保持連貫性損失 CCPL&#xff1a;解決圖像局部失真、視頻幀間的連貫性和閃爍 提出背景解法&#xff1a;對比度保持連貫性損失&#xff08;CCPL&#xff09; 局部一致性假設 對比學習機制 鄰域調節策略 互信息最大化對比學習&#xff1a;在無需標簽的情況下有效學習區分…