KMP演算法(克努特 莫里斯 普拉特操作)簡介

2021-08-09 04:41:17 字數 2071 閱讀 8439

一,串的模式匹配演算法

子串的定位操作通常稱作串的模式匹配(其中t稱為模式串),是各種串處理系統中最重要的操作之一。求子串位置的定位函式index(s,t,pos)如下:

int index(sstring s,sstring t,int pos)	//乙個字元匹配成功繼續匹配後續字元

else //主串指標後退到出發位置的下一位重新匹配

} if(j > t[0]) return i - t[0];

else return 0;

}

演算法的基本思想是:從主串s的第pos個字元起和模式串t的第乙個字元比較,若相等,則繼續逐個比較後續字元;否則從主串的下乙個字元起再重新和模式串比較。以此類推直到模式串的每個字元以此和主串中的乙個連續的字串行相等,則稱匹配成功,函式值為和模式串t中第乙個字元相等的字元在主串s中的序號,否則稱匹配不成功,函式值為0。這種演算法的時間複雜度為o(m*n)。

二,kmp演算法的基本思路

假設主串為's[1]s[2]s[3]...s[n]',模式串為'p[1]p[2]p[3]...p[m]',當主串的第i個字元與模式串中的第j個字元不相同時,並不用將主串指標回溯,而是可以「移動」模式串,使s[i]與j[k]繼續比較。那麼這個k就應該滿足下面的關係:

k是使得  'p[1]p[2]...p[k-1] '  =  's[i-k+1]s[i-k+2]...s[i-1]'  的最大值

記next[j] = k,如果我們已知匹配串每一位的next[j],則kmp演算法的子串定位函式為:

int index_kmp(sstring s,sstring t,int pos)

else j = next[j];

} if(j > t[0]) return i - t[0];

else return 0;

}

三,next[j]的計算方法

當產生「失配」時,已有的部分匹配結果是:

『p[j-k+1]p[j-k+2]...p[j-1]'  =  's[i-k+1]s[i-k+2]...s[i-1]'

則有:

'p[1]p[2]...p[k-1] '  =  『p[j-k+1]p[j-k+2]...p[j-1]'

首先,由定義知,next[1] = 0,

其次,對於任意的j >= 0,

(1)若p[j] == p[next[j]],即:'p[1]p[2]...p[k] '  =  『p[j-k+1]p[j-k+2]...p[j]'

則有next[j+1] = next[j] + 1.

(2)若p[j] != p[next[j]],則可將問題看做用模式串匹配模式串自己的問題,那麼此時應用p[j]與p[next[next[j]]]比較直到next值為0:

void get_next(sstring t,int next)

else j = next[j];

}}//get_next

四,next[j]計算方法的修正

我們發現如果模式串中有類似「aaabaaaaaaab」的結構,那麼在計算next值的時候會有很多不必要的重複計算,主要原因就是連續有幾個相同的字元,那麼其實這些字元的next值是一樣的,沒有必要反覆計算,所以我們需要對計算next的方法進行一些修正:

void get_next(sstring t,int next)

else j = next[j];

}}//get_next

狄克斯特拉演算法

廣度優先演算法,它找出的是段數最少的路徑 無向圖 如果我們要找出最快的路徑 加權圖 可以使用狄克斯特拉演算法。狄克斯特拉演算法包含四個步驟 1.找出 最便宜 的節點,即可在最短時間內到達的節點 2.更新該節點的鄰居的開銷 3.重複這個過程,直到對圖中的每個節點都這樣做了 4.計算最終路徑 以下圖為例...

狄克斯特拉演算法

是由荷蘭計算機科學家狄克斯特拉於1959 年提出的。是從乙個頂點到其餘各頂點的最短路徑演算法,解決的是有向無環圖中最短路徑問題,且不能有負權邊。狄克斯特拉演算法主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。示例 找出從起點到終點的最短路徑 當前起點到各點的花費,選擇最小且沒有被檢...

(原創)狄克斯特拉演算法

1.廣度優先搜尋用於計算非加權圖中的最短路徑 2.狄克斯特拉演算法用於計算加權圖中的最短路徑 不能帶有負權邊 備註 當圖的每條邊都帶有乙個數字時,這些數字成為權重。帶權重的圖稱為加權圖,反之稱為非加權圖。1.從起點開始。2.找到該點最便宜的鄰居節點。3.若該節點的開銷優於之前記錄的開銷,則更新該節點...