偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

字符串匹配的KMP算法

開發(fā) 后端 前端 算法
許多算法可以完成這個任務(wù),Knuth-Morris-Pratt算法(簡稱KMP)是最常用的之一。它以三個發(fā)明者命名,起頭的那個K就是著名科學(xué)家Donald Knuth。

字符串匹配是計(jì)算機(jī)的基本任務(wù)之一。

舉例來說,有一個字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一個字符串"ABCDABD"?

[[72072]]

許多算法可以完成這個任務(wù),Knuth-Morris-Pratt算法(簡稱KMP)是最常用的之一。它以三個***命名,起頭的那個K就是著名科學(xué)家Donald Knuth。

[[72073]]

這種算法不太容易理解,網(wǎng)上有很多解釋,但讀起來都很費(fèi)勁。直到讀到Jake Boxer的文章,我才真正理解這種算法。下面,我用自己的語言,試圖寫一篇比較好懂的KMP算法解釋。

1.

首先,字符串"BBC ABCDAB ABCDABCDABDE"的***個字符與搜索詞"ABCDABD"的***個字符,進(jìn)行比較。因?yàn)锽與A不匹配,所以搜索詞后移一位。

2.

因?yàn)锽與A不匹配,搜索詞再往后移。

3.

就這樣,直到字符串有一個字符,與搜索詞的***個字符相同為止。

4.

接著比較字符串和搜索詞的下一個字符,還是相同。

#p#

5.

直到字符串有一個字符,與搜索詞對應(yīng)的字符不相同為止。

6.

這時(shí),最自然的反應(yīng)是,將搜索詞整個后移一位,再從頭逐個比較。這樣做雖然可行,但是效率很差,因?yàn)槟阋?quot;搜索位置"移到已經(jīng)比較過的位置,重比一遍。

7.

一個基本事實(shí)是,當(dāng)空格與D不匹配時(shí),你其實(shí)知道前面六個字符是"ABCDAB"。KMP算法的想法是,設(shè)法利用這個已知信息,不要把"搜索位置"移回已經(jīng)比較過的位置,繼續(xù)把它向后移,這樣就提高了效率。

8.

怎么做到這一點(diǎn)呢?可以針對搜索詞,算出一張《部分匹配表》(Partial Match Table)。這張表是如何產(chǎn)生的,后面再介紹,這里只要會用就可以了。

9.

已知空格與D不匹配時(shí),前面六個字符"ABCDAB"是匹配的。查表可知,***一個匹配字符B對應(yīng)的"部分匹配值"為2,因此按照下面的公式算出向后移動的位數(shù):

  移動位數(shù) = 已匹配的字符數(shù) - 對應(yīng)的部分匹配值

因?yàn)?6 - 2 等于4,所以將搜索詞向后移動4位。

10.

因?yàn)榭崭衽cC不匹配,搜索詞還要繼續(xù)往后移。這時(shí),已匹配的字符數(shù)為2("AB"),對應(yīng)的"部分匹配值"為0。所以,移動位數(shù) = 2 - 0,結(jié)果為 2,于是將搜索詞向后移2位。

11.

因?yàn)榭崭衽cA不匹配,繼續(xù)后移一位。

12.

逐位比較,直到發(fā)現(xiàn)C與D不匹配。于是,移動位數(shù) = 6 - 2,繼續(xù)將搜索詞向后移動4位。

#p#

13.

逐位比較,直到搜索詞的***一位,發(fā)現(xiàn)完全匹配,于是搜索完成。如果還要繼續(xù)搜索(即找出全部匹配),移動位數(shù) = 7 - 0,再將搜索詞向后移動7位,這里就不再重復(fù)了。

14.

下面介紹《部分匹配表》是如何產(chǎn)生的。

首先,要了解兩個概念:"前綴"和"后綴"。 "前綴"指除了***一個字符以外,一個字符串的全部頭部組合;"后綴"指除了***個字符以外,一個字符串的全部尾部組合。

15.

"部分匹配值"就是"前綴"和"后綴"的最長的共有元素的長度。以"ABCDABD"為例,

  1.  ?。?quot;A"的前綴和后綴都為空集,共有元素的長度為0;  
  2.  
  3.  ?。?quot;AB"的前綴為[A],后綴為[B],共有元素的長度為0;  
  4.  
  5.   - "ABC"的前綴為[A, AB],后綴為[BC, C],共有元素的長度0;  
  6.  
  7.  ?。?quot;ABCD"的前綴為[A, AB, ABC],后綴為[BCD, CD, D],共有元素的長度為0;  
  8.  
  9.   - "ABCDA"的前綴為[A, AB, ABC, ABCD],后綴為[BCDA, CDA, DA, A],共有元素為"A",長度為1;  
  10.  
  11.  ?。?quot;ABCDAB"的前綴為[A, AB, ABC, ABCD, ABCDA],后綴為[BCDAB, CDAB, DAB, AB, B],共有元素為"AB",長度為2;  
  12.  
  13.   - "ABCDABD"的前綴為[A, AB, ABC, ABCD, ABCDA, ABCDAB],后綴為[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的長度為0。 

16.

"部分匹配"的實(shí)質(zhì)是,有時(shí)候,字符串頭部和尾部會有重復(fù)。比如,"ABCDAB"之中有兩個"AB",那么它的"部分匹配值"就是2("AB"的長度)。搜索詞移動的時(shí)候,***個"AB"向后移動4位(字符串長度-部分匹配值),就可以來到第二個"AB"的位置。

原文鏈接:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

責(zé)任編輯:林師授 來源: 阮一峰的網(wǎng)絡(luò)日志
相關(guān)推薦

2024-07-03 11:23:14

2023-12-15 10:27:01

暴力匹配算法Python字符串

2023-04-11 08:54:57

字符串匹配算法

2013-05-06 10:49:21

Boyer-Moore算法字符串匹配

2014-10-30 14:19:13

本文由簡單的字符串匹配

2023-02-26 22:33:32

字符串排列算法

2009-08-07 14:46:59

C#匹配字符串

2016-12-30 13:32:24

字符串算法代碼

2021-09-03 09:41:36

字符串時(shí)間復(fù)雜度

2024-06-26 07:58:06

2016-12-30 13:16:51

字符串算法代碼

2011-03-15 15:20:46

2021-09-10 08:31:54

翻轉(zhuǎn)字符串單詞

2016-12-30 13:37:50

字符串算法代碼

2010-09-09 11:48:00

SQL函數(shù)字符串

2009-08-11 10:26:49

C#算法C#字符串反轉(zhuǎn)

2010-11-26 13:58:48

MySQL字符串匹配

2009-09-16 17:02:15

正則表達(dá)式匹配字符串

2021-03-08 08:23:24

Java字符串截取

2024-04-01 08:41:39

字符串.NET
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號