樸素演算法的思想最好理解當相同時往後匹配,不同時就再從第乙個開始重新匹配,對於無規則亂序還可以,但是如果主串為「abacba」,模式串中如「abab」,我們可以發現當abab後乙個匹配失敗時樸素演算法需要重新從主串的第二個「b」開始與匹配串重新比較,但是kmp就改進了這個缺點,我們已經知道了兩個串前三個一樣,那為什麼不從主串的c與匹配串的第乙個b比較,那主串的c就是主串匹配失敗的位置,匹配串就是匹配失敗時當前位置的前乙個的真子串長度,因為匹配失敗前都已經匹配成功,而只要知道前面的真子串長度。因為是從0開始記錄所以就是真子串的長度而不用加一。
所以我們大概了解了kmp演算法:如果當前字元匹配成功就兩個都往後移,如果失敗,主串位置不變,匹配串返回當前位置前(不含當前字元)真子串的長度。
失效函式也就是求返回當前位置前(不含當前字元)真子串的長度,那麼也可以看成是同樣使用kmp演算法來求。我們令第1個f[0]的為-1
void getfailure(const string &pat, int f)
//求匹配串pat的失效函式值
那麼如果失效函式為求出的每位真子串長度為f;
那麼kmp演算法的主體部分就是
int kmp_find(const string &ob, const string &pat, int p = 0)
// pat匹配串,ob主串,主串第p個位置開始匹配
else
// pat[j]與ob[i]不匹配
j = f[j]; // 尋找新的模式串pat的匹配字元位置
delete f; // 釋f所占用的儲存空間
if (j < pat.getlength())
return -1; // 匹配失敗
else
return i - j; // 匹配成功
}
現在我們發現kmp演算法貌似已經很不錯了,但是假如有乙個匹配串abcab,主串abcad…,如果直接使用kmp。我們會發現第二段匹配時要ab與ad比較,但是如果只看匹配串,因為前面和後面都是ab,所以沒有意義再比較一遍這時候就要改進失效函式,多加一條判斷,當前返回的pat[f[4]]== pat[4],如果相同讓他們的f相同,這樣就像是跳過了這段無意義的比較。
void getfailure(const string &pat, int f)
else
}else
k = f[k];
}
KMP演算法的C 實現
這個問題阮一峰老師講的很清楚,鏈結 這裡我只貼一下我的c 實現 include include include include include using namespace std void buildpatchmatchtable int partmatchtable,char findstr ...
KMP演算法與改進next陣列比較次數的輸出
三 統計kmp子串和主串對比的次數 我使用的是這樣的乙個字元儲存結構 define maxlen 255 typedef struct sstring 那麼,在給字串結構體賦值的時候就無法使用以下形式,而是要用 include using namespace std intmain 如果使用cin來...
C 實現改進的氣泡排序
氣泡排序法 bubble sort 即起泡排序並不能改觀普通排序的時間複雜度,還是o n 2 氣泡排序法是從後往前兩兩比較,然後遍歷整個陣列,猶如魚吐水泡,故起此名。而普通排序法是遍歷整個陣列,然後每個元素和後面的所有元素進行比較,公升序則是後面小的和該元素互換位置,但這樣可能將很小的元素移到後面。...