引言:在上次队列学习后,现在我们再学习串。主要包含KMP算法,现在就开始数据结构与算法的——串的学习。
一.串的定义
定义:串是由零个或者多个字符组成的有限序列,又叫字符串。
串的大部分操作我们曾经都实现过,这里重点介绍KMP算法。
二.朴素的模式匹配算法
朴素模式匹配算法是我们最容易思考到的一种普通算法,其时间复杂度可以认为是O(n*n)的,现在我们来看一下代码。
返回匹配成功之后的首地址,否则返回-1。
#include <iostream>
#include <string.h>
using namespace std;
int simple(char *s,char *p)
{
int ls,lp,i=0,j=0;
ls=strlen(s);
lp=strlen(p);
while(i<ls&&j<lp)
{
if(*(s+i)==*(p+j))
{
i++;
j++;
}
else
{
j=0;
i=i-j+1;
}
}
if(j>=lp)
return i-lp;
else
return -1;
}
int main()
{
char String[]="I love this country";
char pattern[]="this";
int first;
first=simple(String,pattern);
cout<<first<<endl;
return 0;
}
这种方式在很长的字符串中的情况下是很慢的,所以我们需要考虑快的方法。
三.KMP算法
在三位科学家的努力下,KMP诞生了,其时间复杂度降至O(n+m),这大大提高了我们的匹配速度。
现在我们来看下代码。返回匹配成功之后的首地址,否则返回-1
#include <iostream>
#include <string.h>
using namespace std;
int next[255];//定义next数组
void buildnext(char *pp,int *n)
{
int i,j,lp;
lp=strlen(pp);
next[0]=-1;
for(i=1;i<lp;i++)
{
j=next[i-1];
while((j>=0)&&*(pp+j)!=*(pp+j+1))
j=next[j];
if(*(pp+j+1)==*(pp+i))
next[i]=j+1;
else
next[i]=-1;
}
}
int KMP(char *s,char *p)
{
int lp,ls,i,j,l;
lp=strlen(p);
ls=strlen(s);
buildnext(p,next);//初始化next数组
i=j=0;
while(i<ls&&j<lp)
{
if(*(s+i)==*(p+j))
{
i++;
j++;
}
else if(j>0)
j=next[j-1]+1;
else
i++;
}
if(j>=lp)
return i-lp;
else
return -1;
}
int main()
{
char String[]="I love this country";
char pattern[]="this";
int first;
first=KMP(String,pattern);
cout<<first<<endl;
return 0;
}
后记
这次的串操作基本就结束了,其中的思想在以后的文章中会补全,我们将继续往下学习