目錄 題目描述 演算法核心 代碼
目錄 1.題目描述
題目來自於hihocoder:http://hihocoder.com/problemset/problem/1015
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,表示模式串在原串中出現的次數。
範例輸入
5HAHAHAHAWQNWQNADAADADADABABABBBABABABABABABABABBDADADDAADAADDAAADAAD
範例輸出
31310
2.演算法核心
本題目求得是模式串在原串中出現的次數。我們通過在模式串的最後一位添加一個特殊字元$當模式串走到最後一位時候退回到新的位置進行比較 3.代碼
#include<iostream>#include<vector>#include<string>using namespace std;void NextArrayCal(string &str,vector<int> &next){ int j=0,k=-1; next[0]=-1; while(j<str.size()-1) { if(k==-1||str[j]==str[k]) { j++,k++; if(str[j]!=str[k]) next[j]=k; else next[j]=next[k]; next[j]=k; } else k=next[k]; }}int KMPindex(string &str,string&pat){ vector<int>next(pat.size()); NextArrayCal(pat,next); int i=0,j=0; int res=0; int strsize=str.size(),patsize=pat.size(); while(i<strsize) { if(j==-1||str[i]==pat[j]) { i++;j++; } else{ j=next[j]; } if(j>=patsize-1) { ++res; j=next[patsize-1]; } } return res;}int main(){ int tn; cin>>tn; string str; string pat; str.reserve(1000008); pat.reserve(10008); for(int ye=0;ye<tn;++ye) { cin>>pat; pat+="$"; cin>>str; cout<< KMPindex(str,pat)<<endl; }}