目的:查找主串中所含字串的位置
两种算法:
1.BF(暴力破解法)
2.KMP
BF:字串从头开始依次比较
代码:
#include<stdio.h>
#define XAZSIZE 100
#define error -1
typedef struct{
char ch[MAXSIZE+1];//加一的原因是舍弃ch[0]的空间,
//将ch[1]作为第一个元素,后面便于理解。
int length;
}SString;
int index_BF(SString S,SString T){//S为主串。T为字串
int i=1,j=1;
while(i<=S.length&&j<=T.length]<=T.length){
if(S.ch[i]==T.ch[j]){
i++;
j++;
}else{
i=i-j+2;
j=1;//匹配失败,j回到初始值,i回到初始值再向前移动一格
}
}
if(j>=T.length) return i-T.length;//匹配成功,返回字串在主串中的地址
else return error;//匹配失败
}
int main(){
return 0;
}
下面介绍KMP模式算法:原理b站天勤
这里简单记叙求next数组:
求next数组时忽略主串,只看模式串(字串),假如子串元素个数是5,构造一个a[5]数组(0号位忽略是数组下标等于逻辑上的元素位置)。则先看子串前两位,公共前后缀的大小为0(公共前后缀不能是本身),a[2]记为1,可以得出任意字串的next数组a[2]=1.意思是当字串第二位与当前主串就不匹配时,字串下一次比较时从0+1=1号位开始比较。再看字串前两位,假如是aa,因此公共前后缀为1,则a[3]记为0+1=1,意思是当字串的前两位与主串匹配,而第三位与主串不匹配时,下一次匹配直接从子串的的第一位开始匹配。
所以a[1]=0是什么意思呢:
在任意子串中都有a[1]=0,其含义和next数组其他位置稍有区别,意思是当第一位就不匹配时,下一次匹配从子串的一号位与主串的下一位开始比较。而其他情况下下一次匹配是从主串的下n位开始比较,这里n是当前匹配中前n位主串与子串相同。即next数组的下标。
next数组的代码原理非常精妙,参考b站KMP算法之求next数组代码讲解(凡三爱学习
代码
#include<stdio.h>
#define MAXSIZE 100
#define error -1
#include<stdlib.h>
typedef struct{
char ch[MAXSIZE+1];//加一的原因是舍弃ch[0]的空间,
//将ch[1]作为第一个元素,后面便于理解。
int length;
}SString;
//BF算法
int index_BF(SString S,SString T){//S为主串。T为字串
int i=1,j=1;
while(i<=S.length&&j<=T.length){
if(S.ch[i]==T.ch[j]){
i++;
j++;
}else{
i=i-j+2;
j=1;//匹配失败,j回到初始值,i回到初始值再向前移动一格
}
}
if(j>=T.length) return i-T.length;//匹配成功,返回字串在主串中的地址
else return error;//匹配失败
}
//KMP算法
int* GetNext(SString T){
int i=1;
int*next=(int*)malloc((MAXSIZE+1)*sizeof(int));
next[1]=0;
int j=0;
while(i<T.length){//这里<或者<=都可以,因为T.c的最后一个元素是什么与next数组无关
if(j==0||T.ch[i]==T.ch[j]){
i++;
j++;
next[i]=j;
}else{
j=next[j];
}
}
return next;
}
int index_KMP (SString S,SString T,int pos){
int i=pos;
int*next;
int j=1;//pos指针确定了从主串的第几位之后开始查找
next=GetNext(T);//得到next数组
while(i<=S.length&&j<=T.length){
if(j==0||S.ch[i]==T.ch[j]){//j==0的情况是对应子串与主串在第一位就不匹配的情况,
//此时j=next[1]=0,则下一次进入循环是主串向下移动一位,子串从头开始。
i++;
j++;
}else{
j=next[j];
}
if(j<=T.length)return error;//匹配失败
else return i-T.length;
}
}
int main(){
return 0;
}
现在介绍一下next数组的改进版,nextval数组,