func Index(s, sep []byte) int {
n := len(sep)
switch {
case n == 0:
return 0
case n == 1:
return IndexByte(s, sep[0])
case n == len(s):
if Equal(sep, s) {
return 0
}
return -1
case n > len(s):
return -1
case n <= bytealg.MaxLen:
// Use brute force when s and sep both are small
if len(s) <= bytealg.MaxBruteForce {
return bytealg.Index(s, sep)
}
c0 := sep[0]
c1 := sep[1]
i := 0
t := len(s) - n + 1
fails := 0
for i < t {
if s[i] != c0 {
// IndexByte is faster than bytealg.Index, so use it as long as
// we're not getting lots of false positives.
o := IndexByte(s[i:t], c0)
if o < 0 {
return -1
}
i += o
}
if s[i+1] == c1 && Equal(s[i:i+n], sep) {
return i
}
fails++
i++
// Switch to bytealg.Index when IndexByte produces too many false positives.
if fails > bytealg.Cutover(i) {
r := bytealg.Index(s[i:], sep)
if r >= 0 {
return r + i
}
return -1
}
}
return -1
}
c0 := sep[0]
c1 := sep[1]
i := 0
fails := 0
t := len(s) - n + 1
for i < t {
if s[i] != c0 {
o := IndexByte(s[i:t], c0)
if o < 0 {
break
}
i += o
}
if s[i+1] == c1 && Equal(s[i:i+n], sep) {
return i
}
i++
fails++
if fails >= 4+i>>4 && i < t {
// Give up on IndexByte, it isn't skipping ahead
// far enough to be better than Rabin-Karp.
// Experiments (using IndexPeriodic) suggest
// the cutover is about 16 byte skips.
// TODO: if large prefixes of sep are matching
// we should cutover at even larger average skips,
// because Equal becomes that much more expensive.
// This code does not take that effect into account.
j := indexRabinKarp(s[i:], sep)
if j < 0 {
return -1
}
return i + j
}
}
return -1
}
Index 函数解析
计算子byte长度 n
n == 0
返回0.(这里表示空[]byte包含于任意[]byte类型的slice)
n == 1
子byte只有一个byte,可以通过IndexByte进行校验包含关系,IndexByte是通过bytealg包中的IndexByte来实现的
n == len(s)
子byte和父byte长度相等,通过Equal函数进行字符串是否相同的比较
n > len(s)
子byte长度大于父byte长度,返回-1(即不包含)
n <= bytealg.MaxLen
子byte长度小于Index函数子串可搜索的最大长度
父串长度<=最大暴力破解长度(不知道咋翻译),返回bytealg.Index查询结果
父串长度>最大暴力破解长度,首页铆定到和子串第一个byte相同的位置,比较铆定第二位和子串第二位是否相等,相等则比较从铆定位置长度为子串长度的父串与子串是否相等,相等返回铆定位置。不相等错误次数fails累加。铆定位置累加i++,如果错误次数多过bytealg.Cutover的限制,使用bytealg.Index进行查询。
上述过程没有符合条件的,当错误次数fails >= 4+i >> 4 && i < t时,使用RabinKarp算法进行子串的查找。
版权声明:本文为weixin_40341587原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。