kmp演算法是模式匹配的一種演算法,他的思想是,當我們進行模式匹配的時候,不用像暴力解法那樣乙個乙個字元去比較,而是從前一串字元的最大前字尾開始匹配,這樣就節省了不少時間
數學推導:
假如i代表主串指標,j代表子串指標
如果有:
i2 == j2;
j1 != j2;
那麼i2 != j1,我們在後乙個字元失配 的時候,可以直接跳過i2
先來看暴力演算法
//擷取字串//
status substring(string a, int pos,int t,string b)
for (i = pos,j =0 ; t > 0; t--,i++,j++)
b[j] = '\0';//這一步一定要有,沒有的話就會變成燙
return ok;
}//模式匹配的暴力演算法//
status brute_force(string a, string b, int pos)
else
} //執行到這裡代表沒找到
printf("\n不匹配\n");
return error;
}}
接下來看kmp演算法,kmp演算法分兩部分,第一部分是求next陣列,也就是當某乙個位置失配的時候,應該直接跳到子串的哪乙個位置進行比較(這裡說的就是失配的那個位置)。。
next陣列第乙個元素都是等於0的,第0個元素不用管,後面的元素就是前面的字串最大匹配的前字尾數量加一。
比如第二個字元和第乙個字元不一樣,那麼第二個字元前面的字串數量就是1(只有乙個字元),但是匹配的前字尾為0(1個字元不存在匹配的前字尾),那麼next[2]=0+1=1;
next陣列的寫入函式:
//next陣列的實現
void get_next(string b,int *next)
else
}}
然後就是kmp演算法,當我們得到了next陣列之後,就可以用陣列進行模式匹配,還是和暴力解法一樣,ij分別指向主串和子串(模式串),加入相等就ij分別加一,不相等就用next陣列為嚮導對模式串進行指南(指導它該從哪乙個位置開始進行比較)。
//kmp演算法主函式
status index_kmp(string a, string b, int pos)
else
} //跳出迴圈的時候如果j大於子串長度則表示匹配
if (j > b[0])
else
}
但是,我們的next函式是可以進行改進的。
原理是這樣的,假如i3 != j3,j2 == j3,那麼,j2 != i3,也就是說此時重複的比較就是多餘並且可以去掉的
改進next函式的思路是:在進行next賦值的時候我們要多考慮一步,如果將要賦值的字尾和加一後的字首相等的話,那麼他們的next值實際上應該是一樣的,如果不這麼做的話,實際上執行kmp演算法的時候會先指導到前乙個相同的字元,然後再執行它的next陣列值,這樣做就很多餘而且浪費時間。
//改進之後的next函式
void get_nextval(string b, int *nextval)
else
} else
}}
下面附上所有的**
#include "stdafx.h"
#include #include #include #define ok 1
#define error 0
#define maxsize 20
typedef char elemtype;
typedef char string;
typedef int status;
//擷取字串//
status substring(string a, int pos,int t,string b)
for (i = pos,j =0 ; t > 0; t--,i++,j++)
b[j] = '\0';//這一步一定要有,沒有的話就會變成燙
return ok;
}//模式匹配的暴力演算法//
status brute_force(string a, string b, int pos)
else
} //執行到這裡代表沒找到
printf("\n不匹配\n");
return error; }}
//kmp演算法//
//next陣列的實現
void get_next(string b,int *next)
else }}
//改進之後的next函式
void get_nextval(string b, int *nextval)
else
} else }}
//kmp演算法主函式
status index_kmp(string a, string b, int pos)
else
} //跳出迴圈的時候如果j大於子串長度則表示匹配
if (j > b[0])
else
}int main()
輸出結果:
資料結構 字串匹配KMP
kmp主要用於字串匹配 關鍵在於next陣列的求解,當匹配不成功的時候模式串的回退位置就由next陣列決定。next陣列只與主串有關,其求解過程就運用到了kmp思想,求解過程網上很多,個人覺得比較難以理解。next陣列應用,下標從1開始 字首與字尾的最大匹配長度,next i 為字首與字尾的最長匹配...
資料結構 字串 模式匹配
我們先把模式串標出序號 接著把模式串所有字首依次列出來 接下來把每乙個子串相等的字首和字尾的最大長度求出,舉個例子 abaab 觀察子串,前字尾ab相同,因此返回2 5.依次類推,我們可以得到每乙個子串對應的一組序列 當時這組資料並不是所要求的next陣列,可以將其稱為部分匹配值表,相應c 如下 獲...
演算法與資料結構 字串模式匹配 KMP 演算法
在乙個很長的字串 t 中,查詢是否存在子字串 p。例如搜尋引擎收錄的大量 資料,當使用者輸入關鍵字後,就會在這些資料中進行匹配,並返回合適的 語義 假定字串長度為 j,則所有字串都在 0,j 這樣的集合中。返回首次匹配的字元的位置。注意這裡呼叫方需要判斷位置是否正確,例如對於長度為 i 的字串,要查...