【重學(xué)數(shù)據(jù)結(jié)構(gòu)與算法(JS)】字符串匹配算法(一)——BF算法

前言

一切都要從 LeetCode 的第 28 題 實(shí)現(xiàn) strStr()開(kāi)始說(shuō)起雏门,當(dāng)自己腦子里的第一種暴力查找法寫(xiě)出來(lái)并 AC 之后搓逾,還是覺(jué)得不滿足尺迂,決定把能找到的解法都理解了具温,于是便有了這個(gè)系列。

字符串匹配的整體思路

當(dāng)我理解完四種經(jīng)典的匹配算法之后癞揉,總結(jié)了一下這類操作的核心:

  1. 模式串主串進(jìn)行比較
    • 從前往后比較
    • 從后往前比較
  2. 匹配時(shí)纸肉,比較主串模式串的下一個(gè)位置
  3. 失配時(shí),
    • 模式串中尋找一個(gè)合適的位置
      • 如果找到,從這個(gè)位置開(kāi)始與主串當(dāng)前失配位置進(jìn)行比較
      • 如果未找到喊熟,從模式串的頭部與主串失配位置的下一個(gè)位置進(jìn)行比較
    • 主串中找到一個(gè)合適的位置柏肪,重新與模式串進(jìn)行比較

所以總的來(lái)說(shuō),之所以會(huì)有這么多種匹配算法芥牌,本質(zhì)上就是一些大神對(duì)第1步和第3步進(jìn)行了優(yōu)化烦味,這個(gè)核心思路一定要牢牢的先記在腦子里呼胚,這樣之后理解優(yōu)化的匹配算法就不會(huì)一臉懵逼宵溅。

算法介紹與分析

介紹

BF 算法付呕,Brute-Force(暴力)法的簡(jiǎn)稱灸芳,完全沒(méi)有優(yōu)化,每次失配時(shí)從主串的下一個(gè)位置進(jìn)行比較魔种,直到比較結(jié)束悠栓。

分析

算法描述如下:

  1. 模式串主串從前往后比較
  2. 匹配時(shí)色解,比較主串模式串的下一個(gè)位置
  3. 失配時(shí)痘昌,從主串下一個(gè)位置開(kāi)始與模式串的頭部重新開(kāi)始比較

我們假設(shè)有 主串 ABABBBAAABABABBA模式串 ABABABB 钥勋,
下面放五張圖來(lái)理解一下這個(gè)過(guò)程:

QQ20200112-160741.png

QQ20200112-161000.png

上面這兩幅圖,表現(xiàn)的是第1步和第2步控汉,可以看出:

  1. S[0]P[0] 開(kāi)始從頭往后比較
  2. 如果匹配笔诵,比較S[i++]S[j++]
QQ20200112-161423.png
QQ20200112-161548.png

上面這兩幅圖返吻,則表現(xiàn)的時(shí)第3步姑子,可以看出:

  1. 如果 S[i]P[j] 失配
  2. j = 0P[0] 也就是模式串頭部開(kāi)始與主串下一個(gè)位置S[i - (j - 1)]開(kāi)始繼續(xù)進(jìn)行匹配

重復(fù)上述兩步,直到下圖完全匹配或者找不到模式串為止

QQ20200112-162337.png

代碼

思路還是很好理解的测僵,但是代碼怎么寫(xiě)呢街佑?
其實(shí)我一直覺(jué)得刷 LeetCode 除了鞏固與提高數(shù)據(jù)結(jié)構(gòu)與算法的能力之外,最重要的就是訓(xùn)練一種把思路翻譯成代碼的能力捍靠,下面我來(lái)嘗試翻譯一下上述的算法思路沐旨。

1、先進(jìn)行極端情況的排除

carbon.png

這個(gè)操作應(yīng)該是刷題刷多了榨婆,像以前做數(shù)學(xué)題寫(xiě)“解”的操作

2磁携、寫(xiě)出整體的結(jié)構(gòu)

  1. 從算法的思路很容易看出,這里的“重復(fù)上訴兩步”良风,明顯是要翻譯成循環(huán)操作
  2. 如果是循環(huán)谊迄,那么終止條件是什么闷供,可以很快想到,只有兩種終止情況:
    • 主串中沒(méi)有找到 模式串的匹配统诺,此時(shí) i = haystack.length
    • 主串中找到了模式串的匹配歪脏,此時(shí) j = needle.length
  3. 算法處理過(guò)程主要是兩步,所以這里一定有一個(gè)分支結(jié)構(gòu)
    • 匹配
    • 失配
  4. 如果沒(méi)找到粮呢,直接 return -1 就好了婿失,但要是找到了,應(yīng)該怎么確定那個(gè) index 的值呢啄寡?根據(jù)上面成功的圖豪硅,我們可以發(fā)現(xiàn),匹配的位置 8挺物,是等于 主串的末尾 14 減去 模式串的末尾 6 得到的舟误,也就是最后匹配的那個(gè) index = i - j
carbon的副本.png

3、補(bǔ)充具體操作

根據(jù)算法分析里的描述姻乓,很容易知道

  1. 匹配嵌溢,i++; j++; 比較各自的下一位
  2. 失配,i = i - (j - 1); j = 0;重新進(jìn)行下一輪匹配
carbon的副本2.png

總結(jié)

至此蹋岩,整個(gè)BF算法的分析與編寫(xiě)就完成了赖草,雖然它是一個(gè)毫無(wú)優(yōu)化的結(jié)構(gòu),但是體現(xiàn)出了所有字符串匹配算法的基本思想剪个,計(jì)算機(jī)不是人秧骑,可以通過(guò)眼睛觀察和大腦思考來(lái)進(jìn)行定位,它只能通過(guò)一個(gè)一個(gè)字符的比較來(lái)進(jìn)行判定扣囊,接下來(lái)的算法乎折,就開(kāi)始運(yùn)用到一些騷操作來(lái)進(jìn)行優(yōu)化這個(gè)匹配的過(guò)程。

后記

“字符串匹配算法”是“重學(xué)數(shù)據(jù)結(jié)構(gòu)與算法”系列筆記中的一個(gè)章節(jié)侵歇,細(xì)分為以下幾個(gè)部分骂澄,之后會(huì)陸續(xù)填坑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末惕虑,一起剝皮案震驚了整個(gè)濱河市坟冲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溃蔫,老刑警劉巖健提,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異伟叛,居然都是意外死亡私痹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)紊遵,“玉大人雹锣,你說(shuō)我怎么就攤上這事●希” “怎么了蕊爵?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)桦山。 經(jīng)常有香客問(wèn)我攒射,道長(zhǎng),這世上最難降的妖魔是什么恒水? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任会放,我火速辦了婚禮,結(jié)果婚禮上钉凌,老公的妹妹穿的比我還像新娘咧最。我一直安慰自己,他們只是感情好御雕,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布矢沿。 她就那樣靜靜地躺著,像睡著了一般酸纲。 火紅的嫁衣襯著肌膚如雪捣鲸。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,079評(píng)論 1 285
  • 那天闽坡,我揣著相機(jī)與錄音栽惶,去河邊找鬼。 笑死疾嗅,一個(gè)胖子當(dāng)著我的面吹牛外厂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播代承,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼汁蝶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了次泽?” 一聲冷哼從身側(cè)響起穿仪,我...
    開(kāi)封第一講書(shū)人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤席爽,失蹤者是張志新(化名)和其女友劉穎意荤,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體只锻,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡玖像,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捐寥。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笤昨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出握恳,到底是詐尸還是另有隱情瞒窒,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布乡洼,位于F島的核電站崇裁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏束昵。R本人自食惡果不足惜拔稳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望锹雏。 院中可真熱鬧巴比,春花似錦、人聲如沸礁遵。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)佣耐。三九已至铲球,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晰赞,已是汗流浹背稼病。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掖鱼,地道東北人然走。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像戏挡,于是被迫代替她去往敵國(guó)和親芍瑞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345