目录
KMP讲解
帮你把KMP算法学个通透!(理论篇)_哔哩哔哩_bilibili
帮你把KMP算法学个通透!(求next数组代码篇)_哔哩哔哩_bilibili
28.找出字符串中第一个匹配项的下标
题目链接:力扣
题目描述:给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
示例:
输入:haystack = "cleetode", needle = "leeto"
输出:1
1.BF算法
暴力算法。BF的基本思想是将目标串的第一个字符与模式串的第一个字符进行比较,若相等则继续比较目标串和模式串的第二个字符;若不相等则比较目标串的第二个字符与模式串的第一个字符,一次比较下去得到最终匹配的结果。
int strStr(char * haystack, char * needle){
int i=0,j=0;
while(i<strlen(haystack)&&j<strlen(needle)){
if(S.ch[i]==T.ch[j]){
i++;j++;
}
else{
i=i-j+1;
j=0;
}
}
if(j>=strlen(needle))
return i-strlen(needle);
else
return 0;
}
2.KMP算法
next数组(前缀表)决定不匹配的情况下回退到哪个位置,重点是next数组的实现。
求next数组的四个步骤:
- 初始化
- 处理前后缀相同的情况
- 处理前后缀不相同的情况
- 更新next数组
next数组填充部分代码:
//填充next数组(前缀表)
void Getnext(int* next,char* s,int size){
next[0]=0;
//i表示前缀末尾的下标,j表示后缀末尾的下标
for(int i=1,j=0;i<size;i++){
//处理前后缀不相同的情况
while(j>0&&s[i]!=s[j]){
//j回退到next前一位的下标处
j=next[j-1];
}
//处理前后缀相同的情况
if(s[i]==s[j]){
j++;
}
//更新next数组的值
next[i]=j;
}
}
主体代码:
int strStr(char* haystack, char* needle) {
//n为目标串的长度,m为模式串的长度
int n=strlen(haystack);
int m=strlen(needle);
//模式串为空,返回0
if(m==0) return 0;
//构建next数组
int* next=(int*)malloc(sizeof(int)*m);
Getnext(next,needle,m);
//找目标串和模式串匹配的下标
for(int i=0,j=0;i<n;i++){
//处理不等
while(j>0&&haystack[i]!=needle[j]){
j=next[j-1];
}
//处理相等
if(haystack[i]==needle[j]){
j++;
}
//模式串遍历结束
if(j==m){
return i-m+1;
}
}
return -1;
}