一切都要從 LeetCode
的第 28 題 實現 strStr()
開始提及,當本身腦子裏的第一種暴力查找法寫出來並 AC 以後,仍是以爲不知足,決定把能找到的解法都理解了,因而便有了這個系列。算法
當我理解完四種經典的匹配算法以後,總結了一下這類操做的核心:segmentfault
將模式串
和主串
進行比較數據結構
主串
和模式串
的下一個位置失配時,優化
在模式串
中尋找一個合適的位置spa
* 若是找到,從這個位置開始與`主串`當前失配位置進行比較 * 若是未找到,從`模式串`的頭部與`主串`失配位置的下一個位置進行比較
主串
中找到一個合適的位置,從新與模式串
進行比較因此總的來講,之因此會有這麼多種匹配算法,本質上就是一些大神對第1步和第3步進行了優化,這個核心思路必定要緊緊的先記在腦子裏,這樣以後理解優化的匹配算法就不會一臉懵逼。翻譯
BF 算法,Brute-Force(暴力)法的簡稱,徹底沒有優化,每次失配時從主串
的下一個位置進行比較,直到比較結束。3d
算法描述以下:code
模式串
和主串
從前日後比較 主串
和模式串
的下一個位置主串
的下一個位置開始與模式串
的頭部從新開始比較咱們假設有 主串 ABABBBAAABABABBA 和 模式串 ABABABB ,
下面放五張圖來理解一下這個過程:blog
上面這兩幅圖,表現的是第1步和第2步,能夠看出:字符串
S[0]
和 P[0]
開始從頭日後比較S[i++]
和S[j++]
上面這兩幅圖,則表現的時第3步,能夠看出:
S[i]
和 P[j]
失配j = 0
從 P[0]
也就是模式串
頭部開始與主串
的下一個位置S[i - (j - 1)]
開始繼續進行匹配重複上述兩步,直到下圖徹底匹配或者找不到模式串爲止
思路仍是很好理解的,可是代碼怎麼寫呢?
其實我一直以爲刷 LeetCode
除了鞏固與提升數據結構與算法的能力以外,最重要的就是訓練一種把思路翻譯成代碼的能力,下面我來嘗試翻譯一下上述的算法思路。
這個操做應該是刷題刷多了,像之前作數學題寫「解」的操做
若是是循環,那麼終止條件是什麼,能夠很快想到,只有兩種終止狀況:
主串
中沒有找到 模式串
的匹配,此時 i = haystack.length
主串
中找到了模式串
的匹配,此時 j = needle.length
算法處理過程主要是兩步,因此這裏必定有一個分支結構
return -1
就行了,但要是找到了,應該怎麼肯定那個 index
的值呢?根據上面成功的圖,咱們能夠發現,匹配的位置 8
,是等於 主串
的末尾 14
減去 模式串
的末尾 6
獲得的,也就是最後匹配的那個 index = i - j
根據算法分析裏的描述,很容易知道
i++; j++;
比較各自的下一位i = i - (j - 1); j = 0;
從新進行下一輪匹配至此,整個BF算法的分析與編寫就完成了,雖然它是一個毫無優化的結構,可是體現出了全部字符串匹配算法的基本思想,計算機不是人,能夠經過眼睛觀察和大腦思考來進行定位,它只能經過一個一個字符的比較來進行斷定,接下來的算法,就開始運用到一些騷操做來進行優化這個匹配的過程。
「字符串匹配算法」是「重學數據結構與算法」系列筆記中的一個章節,細分爲如下幾個部分,以後會陸續填坑。