解题:http://hihocoder.com/problemset/problem/1015
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。
概念问题
主串S:就是比较长的那个字符串
模式串P:比较短的字符串
算法的功能:从比较长的字符串里面去找到比较短的字符串。
算法核心:
主串S: BBC ABCDAB ABCDABCDABDE
模式串P: ABCDABD
1)分析模式串
2)当匹配到不同的字符的时候去根据next数组去查找最多的移动距离 最多的移动距离是把P的起始位置移动到当期位置移动到上一个匹配数为0的元素。 :移动位数 = 已匹配的字符数 - 对应的部分匹配值
c++源码:
#include<iostream> #include<stdlib.h> #include<vector> using namespace std; inline void NEXT(const string&T,vector<int>&next){//按模式串生成vector,next(T.size()) next[0]=-1; for(int i=1;i<T.size();i++){ int j=next[i-1]; while(T[i-1]!=T[j] &&j >=0) j=next[j];//递推计算 if(T[i-1]==T[j]) next[i]=j+1; else next[i]=0; } } inline string::size_type COUNT_KMP(const string&S,const string&T){ //利用模式串T的next函数求T在主串S中的个数count的KMP算法 //其中T非空, vector<int>next(T.size()); NEXT(T,next); string::size_type index,count=0; for(index=0;index<S.size();++index){ int pos=0; string::size_type iter=index; while(pos<T.size()&&iter<S.size()){ if(S[iter]==T[pos]){++iter;++pos;} else{ if(pos==0) ++iter; else pos=next[pos-1]+1; } } if(pos==T.size() && (iter-index)==T.size()) ++count; } return count; } int main(int argc,char*argv[]) { string S;//="abaabcacabaabcacabaabcacabaabcacabaabcac"; string T;//="ab"; cin>>S; cin>>T; string::size_type count=COUNT_KMP(S,T); cout<<count<<endl; system("PAUSE"); return 0; }
时间: 2024-10-19 05:48:29