找出字符串中第一个匹配项的下标

解法一

暴力

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* @param {string} haystack
* @param {string} needle
* @return {number}
*/
var strStr = function (haystack, needle) {
let i = 0;
j = 0;
while (i < haystack.length) {
if (haystack[i] === needle[j]) {
i++;
j++;
if (j === needle.length) {
// 找到haystack的开始
return i - j;
}
} else {
i = i - j + 1;
j = 0;
}
}
return -1;
};
// console.log(strStr("sadbutsad", "sad"));

解法二

KMP

构建next数组

如果不相等j就回退
直到j不能在回退(为零),next[i] = j

主串和模式串匹配流程

不回退主串,只回退模式串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
* @param {string} haystack
* @param {string} needle
* @return {number}
*/
var strStr = function (haystack, needle) {
function buildNext(pattern) {
const next = Array(pattern.length).fill(0);
let j = 0;
for (let i = 1; i < pattern.length; ++i) {
// 如果不相等j就回退
// 直到j不能在回退(为零),next[i] = j
while (j > 0 && pattern[i] !== pattern[j]) {
j = next[j - 1];
}
if (pattern[i] === pattern[j]) {
j++;
}
next[i] = j;
}
return next;
}
function kmpSearch(text, pattern) {
if (!pattern) return 0;
const next = buildNext(pattern);
let j = 0;
// 主串
// 从零位置开始匹配
for (let i = 0; i < text.length; ++i) {
while (j > 0 && text[i] !== pattern[j]) {
// 如果不匹配只回退模式串
j = next[j - 1];
}
if (text[i] === pattern[j]) {
j++;
}
// 如果匹配到结尾,返回匹配的开始索引
if (j === pattern.length) {
return i - j + 1;
}
}
return -1;
}
return kmpSearch(haystack, needle);
};
// console.log(strStr("sadbutsad", "sad"));

本站由 ao 使用 Stellar 1.29.1 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。