1. 程式人生 > >Hihocoder #1015 : KMP算法

Hihocoder #1015 : KMP算法

hellip 復雜 toggle kmp 做到 你們 memset code 就是

#1015 : KMP算法

時間限制:1000ms 單點時限:1000ms 內存限制:256MB

描述

小Hi和小Ho是一對好朋友,出生在信息化社會的他們對編程產生了莫大的興趣,他們約定好互相幫助,在編程的學習道路上一同前進。

這一天,他們遇到了一只河蟹,於是河蟹就向小Hi和小Ho提出了那個經典的問題:“小Hi和小Ho,你們能不能夠判斷一段文字(原串)裏面是不是存在那麽一些……特殊……的文字(模式串)?”

小Hi和小Ho仔細思考了一下,覺得只能想到很簡單的做法,但是又覺得既然河蟹先生這麽說了,就肯定不會這麽容易的讓他們回答了,於是他們只能說道:“抱歉,河蟹先生,我們只能想到時間復雜度為(文本長度 * 特殊文字總長度)的方法,即對於每個模式串分開判斷,然後依次枚舉起始位置並檢查是否能夠匹配,但是這不是您想要的方法是吧?”

河蟹點了點頭,說道:”看來你們的水平還有待提高,這樣吧,如果我說只有一個特殊文字,你能不能做到呢?“

小Ho這時候還有點暈暈乎乎的,但是小Hi很快開口道:”我知道!這就是一個很經典的模式匹配問題!可以使用KMP算法進行求解!“

河蟹滿意的點了點頭,對小Hi說道:”既然你知道就好辦了,你去把小Ho教會,下周我有重要的任務交給你們!“

”保證完成任務!”小Hi點頭道。

提示一:KMP的思路

提示二:NEXT數組的使用

提示三:如何求解NEXT數組

輸入

第一行一個整數N,表示測試數據組數。

接下來的N*2行,每兩行表示一個測試數據。在每一個測試數據中,第一行為模式串,由不超過10^4個大寫字母組成,第二行為原串,由不超過10^6個大寫字母組成。

其中N<=20

輸出

對於每一個測試數據,按照它們在輸入中出現的順序輸出一行Ans,表示模式串在原串中出現的次數。

樣例輸入

5
HA
HAHAHA
WQN
WQN
ADA
ADADADA
BABABB
BABABABABABABABABB
DAD
ADDAADAADDAAADAAD

樣例輸出

3
1
3
1
0

code

寫的時候不小心將i指針與j指針混用了,幹脆將j改成k。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 
 7 const int N = 1000100;
 8 char T[N],w[N];
 9 int n,m,Ans,C,p[N];
10 
11 void get_p() {
12     p[1] = 0;
13     for (int i=2; i<=m; ++i) {
14         int k = p[i-1];
15         while (k && w[i]!=w[k+1]) k = p[k];
16         if (w[i]==w[k+1]) k++;
17         p[i] = k;
18     }
19 }
20 void kmp() {
21     int k = 0;
22     for (int i=1; i<=n; ++i) {
23         while (k && T[i]!=w[k+1]) k = p[k];
24         if (T[i]==w[k+1]) k++;
25         if (k==m) Ans++;
26     }
27 }
28 int main() {
29     scanf("%d",&C);
30     while (C--) {
31         Ans = 0;
32         memset(p,0,sizeof(p));
33         scanf("%s%s",w+1,T+1);
34         n = strlen(T+1);m = strlen(w+1);
35         get_p();
36         kmp();
37         printf("%d\n",Ans);
38     }
39     return 0;
40 }

Hihocoder #1015 : KMP算法