題目名稱:KMP算法
題目鏈接:http://hihocoder.com/problemset/problem/1015
描述
小Hi和小Ho是一對好朋友,出生在信息化社會的他們對編程產生了莫大的興趣,他們約定好互相幫助,在編程的學習道路上一同前進。
這一天,他們遇到了一隻河蟹,於是河蟹就向小Hi和小Ho提出了那個經典的問題:“小Hi和小Ho,你們能不能夠判斷一段文字(原串)裏面是不是存在那麼一些……特殊……的文字(模式串)?”
小Hi和小Ho仔細思考了一下,覺得只能想到很簡單的做法,但是又覺得既然河蟹先生這麼說了,就肯定不會這麼容易的讓他們回答了,於是他們只能說道:“抱歉,河蟹先生,我們只能想到時間複雜度爲(文本長度 * 特殊文字總長度)的方法,即對於每個模式串分開判斷,然後依次枚舉起始位置並檢查是否能夠匹配,但是這不是您想要的方法是吧?”
河蟹點了點頭,說道:”看來你們的水平還有待提高,這樣吧,如果我說只有一個特殊文字,你能不能做到呢?“
小Ho這時候還有點暈暈乎乎的,但是小Hi很快開口道:”我知道!這就是一個很經典的模式匹配問題!可以使用KMP算法進行求解!“
河蟹滿意的點了點頭,對小Hi說道:”既然你知道就好辦了,你去把小Ho教會,下週我有重要的任務交給你們!“
”保證完成任務!”小Hi點頭道。
輸入
第一行一個整數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
提示:看原題
代碼如下:
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n;
string a,b;
while(scanf("%d",&n)!=EOF)
{
while(n--)
{
int next[10005]={};
cin>>a>>b;
int i=0,len=a.length(),j=-1;
next[0]=-1;
while(i<len)//求1~len的next數組,在下面求時因爲是判斷到不符合時的數==原來數組中的數+1
{
if(j==-1||a[i]==a[j])
{
next[++i]=++j;
// cout<<i<<" "<<next[i]<<endl;
}
else
j=next[j];
}
int ans=0,s=b.length();
i=j=0;
while(i<s)//一個個判斷,到不匹配時就把數組往後移
{
if(j==-1||b[i]==a[j])
{
i++;
j++;
}
else
{
j=next[j];
}
if(j==len)
ans++;
}
printf("%d\n",ans);
}
}
return 0;
}