字串模式匹配--布魯特.福斯演算法視訊講解

清哥好課堂發表於2018-06-24

2.4、字串模式匹配


 資訊網址:www.qghkt.com

騰訊課堂:https://qghkt.ke.qq.com/20個常用演算法


模式串(或子串)在主串中的定位操作通常稱為串的模式匹配,它是各種串處理系統中最重要的運算之一。

2.4.1、布魯特-福斯演算法

【基本思想】

       從主串的第一個字元起與模式串的第一個字元比較,若相等,則繼續逐個字元進行後續比較,否則從主串的第二個字元起與模式串的第一個字元重新開始比較,直至模式串中每個字元依次與主串中的一個連續的字元序列相等時為止,此時稱為匹配成功;如果在主串中不存在與模式串相同的子串,則匹配失敗。

【圖解過程】

給定主串ABCDABCDABBABCDABCDABDD,子串“ABCDABD”

1)第一趟比較,先比較A,然後是BCDAB。

A

B

C

D

A

B

C

D

A

B

B

A

B

C

D

A

B

C

D

A

B

D

D

A

B

C

D

A

B

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

在比較最後一個字元D時,不匹配。

A

B

C

D

A

B

C

D

A

B

B

A

B

C

D

A

B

C

D

A

B

D

D

A

B

C

D

A

B

D

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2)第二趟比較,主串回退到比前一趟加1的位置。子串從0開始。第一個就不匹配。結束本趟。

A

B

C

D

A

B

C

D

A

B

B

A

B

C

D

A

B

C

D

A

B

D

D

 

A

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3)第三趟比較,主串前移一個位置,子串從0開始。第一個還是不匹配。同樣結束本趟。

A

B

C

D

A

B

C

D

A

B

B

A

B

C

D

A

B

C

D

A

B

D

D

 

 

A

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

……

 

i)第i趟比較,找到可以匹配的子串

A

B

C

D

A

B

C

D

A

B

B

A

B

C

D

A

B

C

D

A

B

D

D

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

A

B

C

D

A

B

D

 

 

 

【查詢長度】

假設主串的長度為n,模式串的長度為m,位置序號從1開始。設從主串的第i個字元位置開始與模式串匹配成功,而在前i-1趟匹配中,每趟不成功的匹配都是模式串的第一個字元與主串中相應的字元不相同,則在前i-1趟匹配中,字元間的比較共進行了i-1次,因第i趟成功匹配的字元比較次數為m,所以總的字元比較次數為i-1+m且1≤i≤n-m+1。若在這n-m+1個起始位置上匹配成功的概率相同,則在最好的情況下,匹配成功時字元間的平均比較次數為。最好的情況下為O(n+m)。最壞的情況下,每一趟不成功的匹配都是模式串的最後一個字元與主串中相應的字元不相等。若設第i趟匹配時成功,則前i-1趟不成功的匹配中,每趟都比較了m次,總共比較了(i-1)*m+m,平均比較次數為。由於,所以該演算法在最壞情況下的時間複雜度為O(n*m)。

【演算法程式碼】

/****************************************************************

 * 函式名稱:searchFS

 * 功能描述:布魯特-福斯模式匹配

 * 引數說明:src, 主串

 *                 sub, 模式串

 * 返 回 值:-1,表示不成功,非0的值表示模式串sub在主串src的位置

 * 作    者:www.qghkt.com

 * 建立時間:

*****************************************************************

 * Copyright @ 清哥好課堂  Allrights reserved

*****************************************************************/

int searchFS(const char *src, const char*sub)

{

       int i, j;

       i = 0;

       j = 0;

       int strLen= strlen1(src);

       int tLen =strlen1(sub);

       while(i<strLen && j<tLen)

       {

              if(src[i] == sub[j])

              {

                     ++i;

                     ++j;

              }

              else

              {

                     //主串回退

                     i= i - j + 1;

                     //子串

                     j= 0;

              }

       }

       if (j>= tLen)

       {

              return(i - tLen);

       }

       return -1;

}

 

int searchFS(const char *src, const char*sub, int pos)

{

       int i, j;

       i = pos;

       j = 0;

       int strLen= strlen1(src);

       int tLen =strlen1(sub);

       while(i<strLen && j<tLen)

       {

              if (src[i]== sub[j])

              {

                     ++i;

                     ++j;

              }

              else

              {

                     //主串回退

                     i= i - j + 1;

                     //子串

                     j= 0;

              }

       }

       if (j>= tLen)

       {

              return(i - tLen);

       }

       return -1;

}

 

 

/****************************************************************

 * 函式名稱:searchFSAll

 * 功能描述:查詢模式串在主串中所有的出現的位置

 * 引數說明:locArr, 位置的陣列

 *                 src, 主串

 *                 sub, 模式串

 * 返 回 值:0,表示沒有匹配的,非值,表示有匹配的個數

 * 作    者:www.qghkt.com

 * 建立時間:

*****************************************************************

 * Copyright @ 清哥好課堂  Allrights reserved

*****************************************************************/


相關文章