时间复杂度:
最好的情况O(i+j)
最糟糕的情况O(i*m)
步骤:
1、分别用计数指针i和j指示主串s和子串t,i=0,j=0
2、匹配未到串尾,执行如下循环
(1)s[ i ]==t[ j ],执行i++,j++,继续匹配后续字符
(2)s[ i ]!=t[ j ],回溯一步,i=i-j+1;j=0
3、若子串t[ j ] = =’\0’ ,匹配成功
4、否则匹配失败
#include <bits/stdc++.h>
using namespace std;
string s,t;
int pos;
void Index_BF(string s,string t)
{
int i=0,j=0;
while(i<s.length()&&j<t.length())
{
if(s[ i ] = =t[ j ])
{
i++;j++;
}
else
{
i=i-j+1;j=0;
}
}
if(t[ j ] =='\0')
{
pos=i-t.length()+1;
printf("match success,in father's string n'th:%d\n",pos);
}
else
printf("Match fail \n");
}
int main()
{
while(cin>>s&&s[ 0 ]!='#')
{
cin>>t;
Index_BF(s,t);
}
return 0;
}
BF基础算法用于匹配字符串
统计子串在主串中的出现次数:
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2087
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
string s,t;
int a[100000000];
void get_next(string t,int a[]) //子串t的next函数值并存入串next
{
int i=0,j=-1;
a[0]=-1;
while(i<t.length())
{
if(j==-1||t[i] == t[j])
{
++i;
++j;
if(t[i]==t[j])
a[i]=a[j];
else
a[i]=j;
}
else
j=a[j];
}
}
void get_kmp(string s,string t) //主串s,子串t
{
int cnt=0; //记录剪出个数
int i=0,j=0; //i记录主串,j记录子串
while(i<s.length()) //子串与主串均没有比较到串尾
{
if(j==-1||s[i]==t[j]) //比较后续字符串
{
++i;
++j;
}
else
j=a[j]; //模式串向右移动
if(j==t.length()) //匹配成功一次,主串还没有到串尾
{
++cnt; ///主串s中判断过的位置不需要再次进行判断,所以直接让j=0即可
j=0; //子串计数器为初始状态
}
}
printf("%d\n",cnt); //输出
}
int main()
{
while(cin>>s&&s[0]!='#')
{
cin>>t;
get_next(t,a);
get_kmp(s,t);
}
return 0;
}
时间复杂度: O(i * j),实际的执行时间O(i + j) 特点:指示主串的指针不需要回溯,整个匹配过程对主串进行扫描
#include <bits/stdc++.h>
using namespace std;
string s,t;
int a[10000000];
void get_next(string t,int a[])
{
int i=0,j=-1;
a[0]=-1;
while(i<(t.length()))
{
if(j==-1||t[i]==t[j])
{
++i;++j;
if(t[i]!=t[j])
a[i]=j;
else
a[i]=a[j];
}
else
j=a[j];
}
}
void get_KMP(string s,string t)
{
int cnt=0;
int i=0,j=0;
while(i<s.length())
{
if(j==-1||s[i]==t[j])
{
++i;
++j;
}
else
j=a[j];
if(j==t.length())
{
++cnt;
j=0;
}
}
printf("%d\n",cnt);
}
int main()
{
while(cin>>s&&s[0]!='@')
{
cin>>t;
get_next(t,a);
get_KMP(s,t);
}
return 0;
}
看了这篇博客更好的理解KMP,利用子串后移动
www.ruanyifeng.com/blog/2013/05/Knuth–Morris–Pratt_algorithm.html