c語言例項
總結為什麼要用kmp演算法
kmp演算法
kmp演算法主要用於查詢字串,是 d.e.knuth、j,h,morris 和 v.r.pratt 三位神人共同提出的,稱之為 knuth-morria-pratt 演算法,簡稱 kmp 演算法。該演算法相對於 brute-force(暴力)演算法有比較大的改進,主要是消除了主串指標的回溯,從而使演算法效率有了某種程度的提高。
講kmp演算法之前,我們要先講暴力演算法
暴力演算法就是在一段文字中乙個乙個的匹配字串,匹配不成功從頭開始匹配
例如,從下**字中找到"abcabcd"
匹配第七個字元』d』時,沒匹配到,繼續從第二個位置重新開始匹配
匹配第乙個字元』a』時,沒匹配到,繼續從第三個位置重新開始匹配
匹配第乙個字元』a』時,沒匹配到,繼續從第四個位置重新開始匹配
匹配第七個字元』d』時,沒匹配到,繼續從第五個位置重新開始匹配
總共要匹配17次
int
violentmatch
(char text,
char pattern)
//text是文字串,pattern是關鍵字
else
//如果當前字元匹配失敗,pattern從頭開始匹配}if
(j == plen)
//當pattern全部匹配成功,返回匹配位置
return i - j;
else
return-1
;}
每次匹配字串失敗後都要回從頭開始匹配,如果文字串的長度是n,關鍵字的長度是m,那麼演算法效率(最差)就是n*m
我們先認識下字首
字首就是首字元直到除最後乙個字元外的任意組合都叫字首
例如"abaabbabaab",字首有"a",「ab」,「abaa」,「abaab」,「abaabb」,「abaabba」,「abaabbab」,「abaabbaba」,「abaabbabaa」
暴力演算法可以看出,有一些步驟是可以省略的
首先我們可以在關鍵字"abaabbabaab"中,找到與字首相同的組合,該關鍵字中有八組字元和字首是相同的
如下圖所示,字元下面的數字代表與字首有多少字元對應,儲存在next陣列中。
每次匹配失敗後,我們可以在匹配失敗的位置往前找有沒有和字首相同的組合,直接把整個關鍵字移到該組合的位置開始匹配,過程如下四個步驟所示
第一次匹配失敗後,在第6個字元』b』的前面找到"ab"組合是和字首相同的,那麼我們可以把整個關鍵字搬到"ab"位置上繼續匹配,如下圖
第二次匹配失敗後,在第11個字元』b』的前面找到"abaa"組合是和字首相同的,那麼我們可以把整個關鍵字搬到"abaa"位置上繼續匹配,如下圖
第三次匹配失敗後,在第5個字元』b』的前面找到"a"組合是和字首相同的,那麼我們可以把整個關鍵字搬到"a"位置上繼續匹配,如下圖
第三次匹配失敗後,在第2個字元』b』的前面沒有找到和字首相同組合,那麼按暴力演算法一樣往後移一位繼續匹配,如下圖
匹配完成,這就是kmp演算法的原理
比起暴力演算法省了很多步驟,如果關鍵字中沒有與字首相同的組合,那麼和暴力演算法沒區別
kmp能有效的減少暴力演算法中的從頭開始匹配的過程
從關鍵字中找到與字首相同的組合,每次匹配失敗後,從失敗的位置往前找到組合的位置,下次匹配的時候從該位置開始匹配
先從關鍵字中找出所有與字首相同的組合,把組合數儲存在next陣列,在匹配過程中就可以根據next陣列進行優化
//在關鍵字中記錄與字首匹配的組合,記錄在next陣列
void
match_next
(const
char
*pattern,
int*next)
if(pattern[q]
== pattern[k]
) next[q]
= k;
//next[q]對應第q個元素與字首對應數量}}
//kmp演算法
intkmp
(const
char
*text,
const
char
*pattern,
int*next)
if(pattern[q]
== text[i])if
(q == m)
}return-1
;//整個文字串找完都沒有找到字串,返回-1
}
kmp演算法就是在關鍵字中找到與字首相同的組合,儲存在next陣列,比起暴力演算法,kmp演算法可以通過next陣列,在匹配失敗後跳到該組合的位置上繼續匹配
如果文字串的長度是n,關鍵字的長度是m,那麼演算法效率是n+m
職場故事 一天看一遍
低調的力量 一壯小伙牽了一價值百萬的純種藏獒出來遛彎。逢人便炫耀狗好,人要是沒個四五百斤力量的拽都拽不住。這時候看路邊一禿頂老頭,身邊還坐乙隻毛都快要掉光了的狗。他的藏獒對那狗一頓嚎叫,那老狗理都沒理藏獒。小伙不樂意了。說道 老頭,你那狗那麼大,是什麼狗啊?咱倆的狗鬥一下?你的狗輸了給我500,我的...
每次不想學習就看一遍
你要是天天一大早六點起床,吃頓好飯,奔去教室背兩篇新三,八點坐直在教室的前排,使勁不分心不玩手機地聽完三節還是四節課,課間練字背單詞看報紙,放學奔去食堂搶份好飯,回宿舍吃完,洗洗衣服拖拖地消化下,再聽 一倍速聽完聽1.5,1.5聽完聽2倍,聽困了 歇中覺,下午繼續坐直在前排聽完三節課,放學去食堂搶個...
每天看一遍,成功的好習慣
要成功,就馬上準備有所付出吧!這就是每天你應該養成的習慣。1 不說 不可能 2 凡事第一反應 找方法,不找藉口 3 遇到挫折對自己說聲 太好了,機會來了!4 不說消極的話,不落入消極的情緒,一旦發生立即正面處理 5 凡事先訂立目標 6 行動前,預先做計畫 7 工作時間,每一分 每一秒做有利於生產的事...