@@ -59,21 +59,26 @@ func hashstr(sep string) (uint32, uint32) {
59
59
60
60
// Count counts the number of non-overlapping instances of sep in s.
61
61
func Count (s , sep string ) int {
62
- if sep == "" {
63
- return utf8 .RuneCountInString (s ) + 1
64
- }
65
- c := sep [0 ]
66
62
n := 0
67
- if len (sep ) == 1 {
63
+ // special cases
64
+ switch {
65
+ case len (sep ) == 0 :
66
+ return utf8 .RuneCountInString (s ) + 1
67
+ case len (sep ) == 1 :
68
68
// special case worth making fast
69
+ c := sep [0 ]
69
70
for i := 0 ; i < len (s ); i ++ {
70
71
if s [i ] == c {
71
72
n ++
72
73
}
73
74
}
74
75
return n
75
- }
76
- if len (sep ) > len (s ) {
76
+ case len (sep ) > len (s ):
77
+ return 0
78
+ case len (sep ) == len (s ):
79
+ if sep == s {
80
+ return 1
81
+ }
77
82
return 0
78
83
}
79
84
hashsep , pow := hashstr (sep )
@@ -82,17 +87,19 @@ func Count(s, sep string) int {
82
87
h = h * primeRK + uint32 (s [i ])
83
88
}
84
89
lastmatch := 0
85
- for i := len (sep ); ; i ++ {
86
- // Invariant: h = hash(s[i-l : i])
90
+ if h == hashsep && s [:len (sep )] == sep {
91
+ n ++
92
+ lastmatch = len (sep )
93
+ }
94
+ for i := len (sep ); i < len (s ); {
95
+ h *= primeRK
96
+ h += uint32 (s [i ])
97
+ h -= pow * uint32 (s [i - len (sep )])
98
+ i ++
87
99
if h == hashsep && lastmatch <= i - len (sep ) && s [i - len (sep ):i ] == sep {
88
100
n ++
89
101
lastmatch = i
90
102
}
91
- if i >= len (s ) {
92
- break
93
- }
94
- h = h * primeRK + uint32 (s [i ])
95
- h -= pow * uint32 (s [i - len (sep )])
96
103
}
97
104
return n
98
105
}
@@ -115,21 +122,24 @@ func ContainsRune(s string, r rune) bool {
115
122
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
116
123
func Index (s , sep string ) int {
117
124
n := len (sep )
118
- if n == 0 {
125
+ switch {
126
+ case n == 0 :
119
127
return 0
120
- }
121
- c := sep [0 ]
122
- if n == 1 {
128
+ case n == 1 :
129
+ c := sep [0 ]
123
130
// special case worth making fast
124
131
for i := 0 ; i < len (s ); i ++ {
125
132
if s [i ] == c {
126
133
return i
127
134
}
128
135
}
129
136
return - 1
130
- }
131
- // n > 1
132
- if n > len (s ) {
137
+ case n == len (s ):
138
+ if sep == s {
139
+ return 0
140
+ }
141
+ return - 1
142
+ case n > len (s ):
133
143
return - 1
134
144
}
135
145
// Hash sep.
@@ -138,16 +148,17 @@ func Index(s, sep string) int {
138
148
for i := 0 ; i < n ; i ++ {
139
149
h = h * primeRK + uint32 (s [i ])
140
150
}
141
- for i := n ; ; i ++ {
142
- // Invariant: h = hash(s[i-n : i])
151
+ if h == hashsep && s [:n ] == sep {
152
+ return 0
153
+ }
154
+ for i := n ; i < len (s ); {
155
+ h *= primeRK
156
+ h += uint32 (s [i ])
157
+ h -= pow * uint32 (s [i - n ])
158
+ i ++
143
159
if h == hashsep && s [i - n :i ] == sep {
144
160
return i - n
145
161
}
146
- if i >= len (s ) {
147
- break
148
- }
149
- h = h * primeRK + uint32 (s [i ])
150
- h -= pow * uint32 (s [i - n ])
151
162
}
152
163
return - 1
153
164
}
0 commit comments