1
2
3
4
5 package bytealg
6
7 import (
8 "internal/cpu"
9 "unsafe"
10 )
11
12
13 const (
14 offsetPPC64HasPOWER9 = unsafe.Offsetof(cpu.PPC64.IsPOWER9)
15
16 offsetRISCV64HasV = unsafe.Offsetof(cpu.RISCV64.HasV)
17
18 offsetLOONG64HasLSX = unsafe.Offsetof(cpu.Loong64.HasLSX)
19 offsetLOONG64HasLASX = unsafe.Offsetof(cpu.Loong64.HasLASX)
20
21 offsetS390xHasVX = unsafe.Offsetof(cpu.S390X.HasVX)
22
23 offsetX86HasSSE42 = unsafe.Offsetof(cpu.X86.HasSSE42)
24 offsetX86HasAVX2 = unsafe.Offsetof(cpu.X86.HasAVX2)
25 offsetX86HasPOPCNT = unsafe.Offsetof(cpu.X86.HasPOPCNT)
26 )
27
28
29
30 var MaxLen int
31
32
33 const PrimeRK = 16777619
34
35
36
37 func HashStr[T string | []byte](sep T) (uint32, uint32) {
38 hash := uint32(0)
39 for i := 0; i < len(sep); i++ {
40 hash = hash*PrimeRK + uint32(sep[i])
41 }
42 var pow, sq uint32 = 1, PrimeRK
43 for i := len(sep); i > 0; i >>= 1 {
44 if i&1 != 0 {
45 pow *= sq
46 }
47 sq *= sq
48 }
49 return hash, pow
50 }
51
52
53
54 func HashStrRev[T string | []byte](sep T) (uint32, uint32) {
55 hash := uint32(0)
56 for i := len(sep) - 1; i >= 0; i-- {
57 hash = hash*PrimeRK + uint32(sep[i])
58 }
59 var pow, sq uint32 = 1, PrimeRK
60 for i := len(sep); i > 0; i >>= 1 {
61 if i&1 != 0 {
62 pow *= sq
63 }
64 sq *= sq
65 }
66 return hash, pow
67 }
68
69
70
71 func IndexRabinKarp[T string | []byte](s, sep T) int {
72
73 hashss, pow := HashStr(sep)
74 n := len(sep)
75 var h uint32
76 for i := 0; i < n; i++ {
77 h = h*PrimeRK + uint32(s[i])
78 }
79 if h == hashss && string(s[:n]) == string(sep) {
80 return 0
81 }
82 for i := n; i < len(s); {
83 h *= PrimeRK
84 h += uint32(s[i])
85 h -= pow * uint32(s[i-n])
86 i++
87 if h == hashss && string(s[i-n:i]) == string(sep) {
88 return i - n
89 }
90 }
91 return -1
92 }
93
94
95
96 func LastIndexRabinKarp[T string | []byte](s, sep T) int {
97
98 hashss, pow := HashStrRev(sep)
99 n := len(sep)
100 last := len(s) - n
101 var h uint32
102 for i := len(s) - 1; i >= last; i-- {
103 h = h*PrimeRK + uint32(s[i])
104 }
105 if h == hashss && string(s[last:]) == string(sep) {
106 return last
107 }
108 for i := last - 1; i >= 0; i-- {
109 h *= PrimeRK
110 h += uint32(s[i])
111 h -= pow * uint32(s[i+n])
112 if h == hashss && string(s[i:i+n]) == string(sep) {
113 return i
114 }
115 }
116 return -1
117 }
118
119
120
121
122
123 func MakeNoZero(n int) []byte
124
View as plain text