現在我們有母串s,模式串t;
我們傳統的字串匹配都思想是,不管此次匹配成功與否,都是模式串向前移動一位繼續匹配,這樣子效率肯定是很慢的,因為我們根本沒有利用到之前已經匹配過的資訊
kmp演算法就是利用之前匹配的資訊,使模式串前移更多的位,使其效率大大提公升,那麼我們怎麼知道什麼時候前移多少位呢,首先我們假設現在模式串第j位與母串第i位匹配成功
,接下來就是匹配s[i+1]和t[j+1]如果s[i+1]!=t[j+1]那麼按照我們傳統的匹配方法我們這時j變為0,從頭繼續開始匹配,kmp,改進的就是這裡,實際上不用,只用找到,前面匹配過的字首等於字尾的最大長度即可,那麼我們怎找到這個字首等於字尾的最大長度呢(其實我覺的這個才是kmp最難的)我們可以通過預處理的方法求出,開乙個next陣列表長度
為i的字串的字首等於字尾的最大長度是多少,為什麼要這樣定義呢,因為字串下標是從0開始的,這樣的話每次找到最大長度d後那麼t【d】代表的是最大長度後面的字元,就很方便,然後我們怎麼去找出每個位置的最大長度呢,我們可以發現下一位的最大長度只跟上一次的有關,那麼我們可以用乙個變數記錄上一次的的最大長度,然後跟第i位比較就行了(這裡說的有點不清楚,請看**);
kmp模版:
#include#include#include#include#include#include#include#define ll long long
using namespace std;
const int maxn = 1e5;
char s[maxn];
char t[maxn];
int lens;
int lent;
int next[maxn];
void getnext()
if(s[i] == t[k])
if(k == lent)
}return ans;
}int main()
if(s[i] == t[k])
if(k==lent)
}return ans;
}int main()
}
hdu1711
#include#include#include#include#include#includeusing namespace std;
const int maxn = 1e6+50;
int a[maxn];
int b[maxn];
int next[maxn];
int n,m;
int getnext()
if(a[i] == b[k])
if(k==m)
{cout<
兩道相似KMP題
1.poj 3450 coporate identity 這兩題的解法都是列舉子串,然後匹配,像這種題目以後可以不用kmp來做,直接字串自帶的strstr函式搞定,如果字串未出現,該函式返回null。下面貼出其比較。kmp版 1360ms 888kb include include include ...
兩種KMP題 KMP模版整理
最近稍微看了下kmp,不是很懂他們大神的a題姿勢,但是模版總該還是要去學的。其中next陣列的求法有兩處區別。第一種 求主串中模式串的個數。hdu2087 剪花布條和hdu4847 wow such doge 這兩道都比較水可以暴力string find函式過,第乙個 include include...
四道樹狀陣列模版題
概念與實現就 lande 不寫了,反正一大堆 嚴格來說其實不是模版題,但由於實際編碼接近模版題,當作模版題來說 天文學家經常要檢查星星的地圖,每個星星用平面上的乙個點來表示,每個星星都有座標。我們定義乙個星星的 級別 為給定的星星中不高於它並且不在它右邊的星星的數目。天文學家想知道每個星星的 級別 ...