日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

c语言主范式与编码,超详细!终于搞明白KMP算法

發布時間:2025/3/15 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言主范式与编码,超详细!终于搞明白KMP算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

小伙伴們好久不見,今天將開設“數據結構與算法”專欄,一起梳理一遍硬核課程的重要知識點,那我們開始吧

正文

「字符串匹配」是計算機的基本任務之一,舉個栗子,有一個字符串“「aaaaaaca」",我想知道里面是否包含另一個字符串“「aaaac」”,該怎么辦?

這里就會使用到「串的模式匹配算法」,最常見的分別是傳統的「Brute-Force(暴力)算法」和「KMP算法」。

BF算法設計思想

1、主串和模式串逐個字符進行比較

2、當出現「字符串不相同」時,也就是「失配」時,主串的比較位置重置為起始位置的下一個字符位置,模式串的比較位置重置為起始位置

3、匹配成功后返回主串中匹配串的起始位置,否則就返回錯誤代碼

BF算法的設計缺陷及解決方案

在BF算法中,每次失配都需要回溯指向上次比較起始字符的下一個字符。通過觀察發現:在回溯的時候,已匹配似乎「有一部分」沒必要繼續比較了,這樣可以降低算法的「時間復雜度」

「KMP」算法的出現有效地解決了BF算法的缺陷。KMP 算法是 D.E.Knuth、J,H,Morris 和 V.R.Pratt 三位神人共同提出的。

但是這種算法相對于BF算法不太容易理解,網上也有很多解釋,但配圖有點少,總感覺差點意思,下面我通過畫圖的方式詳細介紹KMP算法的設計思想和工作原理

KMP算法設計思想

在匹配過程中出現字符比較不相等時,「主串 S」已比較的位置不回溯,「模式串 T」比較的位置進行移動

在匹配過程中有一個難題需要解決:如何計算「模式串 T」失配時的移動位數?經過三位牛人的研究,設計出了「部分匹配函數」

部分匹配函數

部分匹配函數是KMP算法中最難以理解的部分。首先需要理解「前綴」、「后綴」、「最大共有長度」的概念。

· 前綴:指除了最后一個字符以外,一個字符串的全部頭部組合

· 后綴:指除了第一個字符以外,一個字符串的全部尾部組合

· 最大共有長度(部分匹配值):指前綴和后綴中的最大共有元素,沒有則為0。例如“abab”的前綴為“a”、“ab”、“aba”,后綴為“b”、“ab”、“bab”,最大共有元素為“ab”,所以最大共有長度為 2

回顧一下KMP算法的匹配過程:

紅線框出的部分恰好就是失配時已匹配部分,“aaaa” 的最大共有元素為 “aaa”,這一部分字符就是不需要再重復進行比較直接跳過的字符

在代碼實現過程中,j 移動后的位置 = 模式串 T 的起始位置下標 + 部分匹配值。通常起始下標為 0,因此 j 移動后位置 = 部分匹配值,即 j = next[j],next[j] 就是「部分匹配函數」,j 為失配時的位置

因此接下來就成了對部分匹配函數的是實現。將 “aaaac” 以首字符起始的所有子串的最大共有長度枚舉出來,構成「部分匹配表」,它描述了失配時的下標 j 與部分匹配值的關系

部分匹配表則是通過模式串 T 的自匹配實現:

示例代碼(C語言哦):

/*KMP匹配算法*/

int?KMPCompare(HString?parent,?HString?child,?intpos)?{

int?next[255];

Get_Next(child,?next);

int?i?=?pos?-?1;

int?j?=?0;?????//j用于子串child中的起始位置

while?(i?

if?(j?==?0?||?parent.ch[i]?==?child.ch[j])?{

++i;

++j;

}

else?{

j?=?next[j];????//i不變,j后退

}

}

if?(j?==?child.length)?{

return?(i?+?1)?-?j;

}

return?0;

}

/*部分匹配函數的實現*/

void?Get_Next(HString?child,?int?*?next)?{

int?i?=?0;

int?j?=?-1;

next[0]?=?-1;???//不會用到

while?(i?

if?(j?==?-1?||?child.ch[i]?==?child.ch[j])?{

++i;

++j;

next[i]?=?j;

}

else?{

j?=?next[j];

}

}

}

void?main()?{

/*使用KMP算法匹配串*/

HString?parent,?child;

StrAssign_HeapString(&parent,?"BBC?ABCDAB?ABCDABCDABDE");

StrAssign_HeapString(&child,?"ABCDABD");

printf("Index?=?%d\n",?KMPCompare(parent,?child,?1));

}

復制代碼

關注即可提高學習效率!我是Aime菌,下期再見!Peace~

每天進步一點點,慢一點才能走得更快

總結

以上是生活随笔為你收集整理的c语言主范式与编码,超详细!终于搞明白KMP算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。