找出字符串中第一个匹配的下标(kmp)
kmp最详细的讲解
https://zhuanlan.zhihu.com/p/151421571
题目
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
示例 1:
输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。
示例 2:
输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。
思路
暴力解法这里就不说了,重点是看kmp算法,算法的核心是建立next数组(也叫做前缀表),如何建立这个next数组和拿这个数组来匹配是一个重点,相关细节可以看代码随想录的介绍
kmp算法介绍
代码
class Solution {
public:
//next数组的更新十分神奇,可以好好看看
vector<int> getNext(string needle) {
vector<int> next(needle.size(), 0);
int i= 0;
int j = 1;
for(; j < needle.size(); j++) {
if(needle[j] == needle[i]) {
i++;
}else {
//i要退到两者不相等的位置
while(i > 0 && needle[i] != needle[j]){
i = next[i - 1];
}
if(needle[i] == needle[j]) {
i++;
}
}
next[j] = i;
}
return next;
}
int strStr(string haystack, string needle) {
//使用kmp算法实现的过程,首先是根据needle得出next数组,因为匹配过程要用到这个
//haystack = "abcabcaba" ,needle = "abcaba"; next = 000121为例
vector<int> next = getNext(needle);
int j = 0;
int i = 0;
for(; i < haystack.size(); i++) {
if(haystack[i] == needle[j]) {
j++;
//以上的过程一直持续到i = 5, j = 5,那就不等了
}else {
//怎么跳转的呢,此时跳的是j = 4,也就是看4是怎么跳的
while(haystack[i] != needle[j] && j > 0) {
j = next[j - 1];
}
if(haystack[i] == needle[j]) {
j++;
}
}
if(j == needle.size()) {
break;
}
}
if(j == needle.size()) {
//说明匹配成功了
return i - needle.size() + 1;
}else {
return -1;
}
return -1;
}
};

浙公网安备 33010602011771号