一、BF算法
最简单直观的模式匹配算法是BF(Brute-Fore)算法.
[算法思想]
从主串S的第pos个字符起和模式的第一个字符进行比较,若相等,则进行逐个比较后续字符;否则从主串的下一个字符起再重新和模式的字符比较.
依次类推,直至模式T中的每个字符依次和主串S中的一个连续的字符序列相等,则匹配成功,函数返回值为和模式T中第一个字符相等的字符在主串S中的序号,
否则称匹配不成功,函数返回值为零
[算法描述]
int Index(SString S,SString T,int pos)
{
//返回模式T在主串S中第pos个字符开始第一次出现的位置.若不存在,则返回值为0
//其中,T非空,1<=pos<=StrLength(S)
i=pos; j=1;
while(i<=S[0] && j<=T[0])/* T[0]、S[0]分别用来存储字符串T的长度和S的长度 */
{
if(S[i] == T[i]) //继续比较后继字符
{
++i;
++j;
}
else //指针后退重新开始匹配
{
i=i-j+2; //主串的下一个字符起再重新和模式的字符比较
j=1;
}
}
if(j>T[0])
{
return i-T[0];
}
else
{
return 0;
}
}
2)最坏情况下的平均时间复杂度是O(n*m)
来看一个例子:
[问题描述]
1204 寻找子串位置
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze
题目描述 Description
给出字符串a和字符串b,保证b是a的一个子串,请你输出b在a中第一次出现的位置。
输入描述 Input Description
仅一行包含两个字符串a和b
输出描述 Output Description
仅一行一个整数
样例输入 Sample Input
abcd bc
样例输出 Sample Output
2
数据范围及提示 Data Size & Hint
字符串的长度均不超过100
[代码实现]
#include
#include
using namespace std;
int Index(const string S,const string T)
{
int i=0; int j=0;
while(S[i]&&T[j])
{
if(S[i] == T[j]) //继续比较后继字符
{
++i;
++j;
}
else //指针后退重新开始匹配
{
i=i-j+1; //主串的下一个字符起再重新和模式的字符比较
j=0;
}
}
int TLenth=T.length()-1;
if(j>TLenth )
{
return i-TLenth;
}
return 0;
}
int main()
{
string a,b;
cin>>a>>b;
cout<
二、KMP算法
kmp算法的原理,即求出P0...Pi的最大
求出对应每一位的最大相同前后缀的长度.
void makeNext(const char P[],int next[])
{
int q,k; /*q:模板字符串下标; k:最大前后缀长度*/
int m=strlen(P); /*模板字符串长度*/
next[0]=0;
for(q=1,k=0;q0 && P[q] != P[k]) /*递归的求出P[0]...P[q]的最大的相同的前后缀长度k*/
{
k=next[k-1]; /*不理解没关系看下面的分析,这个while循环是整段代码的精髓所在,确实不好理解*/
}
if(P[q]==P[k]) /*如果相等,那么最大相同前后缀长度加1*/
{
k++;
}
next[q]=k;
}
}
现在着重讲解一下while循环所做的工作:看看它的下一项P[j]是否能和P[q]匹配.如图2所示
[算法描述]#include
#include
void makeNext(const char P[],int next[])
{
int q,k;
int m=strlen(P);
next[0]=0;
for(q=1,k=0;q0 && P[q]!= P[k])
{
k=next[k-1];
}
if(P[q]==P[k])
{
k++;
}
next[q]=k;
}
}
int kmp(const char T[], const char P[],int next[])
{
int n,m;
int i,q;
n=strlen(T);
m=strlen(P);
makeNext(P,next);
for(i=0,q=0;i0 &&P[q]!=T[i])
{
q=next[q-1];
}
if(P[q] == T[i])
{
q++;
}
if(q==m)
{
printf("Pattern occurs with shift:%d\n",(i-m+1));
}
}
}
int main()
{
int i;
int next[20]={0};
char T[]="ababxbababcadfdsss";
char P[]="abcdabd";
printf("%s\n",T);
printf("%s\n",P);
kmp(T,P,next);
for(i=0;i