演算法導論 讀書筆記 字串匹配

2021-09-13 15:46:49 字數 1906 閱讀 2983

字串匹配

一. 定義

在日常生活中,我們常常需要在文字中找到某個模式的所有出現位置,比如輸入字串,需要找到出現這個字串的所有位置,解決這個問題的演算法叫做字串匹配演算法。

字串匹配問題的形式化定義:假設文字是乙個長度為n的陣列t[1...n],而模式是乙個床都為m的陣列p[1...m],其中m<=n,進一步假設p和t的元素都是來自乙個有限字母集q的字元,如q=,或者q=,字元陣列p和t稱為字串。如果0<=s<=n-m,並且t[s+1...s+m]=p[1...m],那麼稱模式p在文字t**現,且偏移為s。字串匹配問題就是找到所有的偏移s,使得在該偏移下,所給的模式p出現在給定的文字t中

二. 樸素字串匹配演算法

樸素字串匹配演算法即暴力列舉演算法,對於每個偏移s,判斷其是否匹配,得到結論。上**

c++**

#include#include#includeusing namespace std;

bool match(string &t,string &p,int s,int m),這樣所有字元都是a-z之間,如果將其減去『a',得到0-25的數值,於是字串就可以當做是d=26進製的連續數字。給定模式p[1...m],假設p是其相應的26進製數字,假設ts表示長度為m的t[s+1...s+m]所對應的26進製數字,其中s=0,1...n-m。當且僅當t[s+1...s+m]=p[1...m]時,ts=p。

為了計算p和t0,我們可以運用霍納法則,時間複雜度為o(m)。

為了計算剩餘的值t1,t2,...,t(n-m),我們可以通過遞推公式,在常數時間根據ts計算t(s+1)。

而d^m-1又可以通過反覆平方法在o(lgm)的時間內完成,因此可以在o(m)內計算p,在o(n-m+1)計算t0..t(n-m)。於是可以用o(m)的處理時間,和o(n-m+1)的匹配時間內找到所有模式p[1..m]在文字t[1..n]**現的位置。

然而,如果m數值過大,我們看到中間運算會出現乙個以m指數增長的d^(m-1)這麼乙個大數,於是p和ts的值會大得使得我們無法處理,為了解決這個問題,我們使用雜湊對映的方式,選取乙個合適的模q來計算p和ts的模,於是過程匹配過程轉變為,在o(m)的時間內計算出模q的p值,在o(n-m+1)時間內計算模q的所有ts值,如果選取q為乙個素數,使得dq剛好在乙個字長以內,那麼可以在float中完成所有運算,遞迴式轉變為

實際上就是將這些「大數「用它對q取模的數來替代。而基於模q的結果並不完美,存在這雜湊衝突,ts mod q==p mod q不能說明ts==q,但如果ts mod q!=p mod q,則說明ts!=q,可作為一種啟發式的方式排除錯誤的匹配,在滿足等號的情況下需要進一步進行一次檢測t[s+1...s+m]=p[1...m],如果q足夠大,那麼這種衝突就越少。

c++**

#include#include#include#includeusing namespace std;

bool match(char* &t,char* &p,int s,int m)

b=b>>1;

a*=a;

}return d;

}int rabin_karp_matcher(char* t,char* p,int d,int q){

int n=strlen(t);

int m=strlen(p);

int *text=(int*)malloc(n*sizeof(int));

int *pattern=(int*)malloc(m*sizeof(int));

int *t=(int*)malloc((n-m+1)*sizeof(int));

for(int i=0;i=0)

cout可以看到在這種啟發式檢查中,當q越大,它衝突的機率就越小,可以估計兩個隨機數對q取模相等的概率是1/q,於是rabin-karp演算法的期望執行時間為o(n)+o(m(v+n/q)),v是實際偏移量。

演算法導論 字串匹配

華電北風吹 天津大學認知計算與應用重點實驗室 最後修改日期 2016 1 4 本文說說我對幾個常用的字串匹配演算法的理解。字串匹配問題是指對於乙個長度為n的文字陣列t n 檢測長度為m的模式文字陣列p m 在t中出現的位置。常見的方法有樸素演算法,rabin karp演算法,有限自動機演算法,kmp...

讀書筆記 演算法導論

第2章演算法入門 浮於表面不如深入其中,送給自己,自己是最大的敵人,那麼就盡最大努力去克服自己,沉思,冷靜,不浮躁!勘誤 在演算法導論第9頁,扼要的扼 內容提要 1 偽 的表示方法 2 插入排序演算法分析 3 迴圈不變式 4 演算法設計之分治法 divide and conquer 5 合併排序演算...

《C primer 讀書筆記》 字串

c 提供了兩種字串的表示 c 風格的字串和標準 c 引入的 string 類型別 1.c 風格的字串 字串被儲存在乙個字元陣列中,一般通過乙個char 型別的指標來操縱它 必須包含相關的 c 標頭檔案 include提供一系列函式,如 返回字串的長度 int strlen const char 比較...