Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(142)

Delta Between Two Patch Sets: src/pkg/strings/strings.go

Issue 160200044: [dev.power64] code review 160200044: build: merge default into dev.power64 (Closed)
Left Patch Set: diff -r be0c14f62257b42485019e9e1db23cf40d2e249f https://code.google.com/p/go Created 10 years, 4 months ago
Right Patch Set: diff -r be0c14f62257b42485019e9e1db23cf40d2e249f https://code.google.com/p/go Created 10 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/strconv/quote.go ('k') | src/pkg/strings/strings_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // Package strings implements simple functions to manipulate strings. 5 // Package strings implements simple functions to manipulate strings.
6 package strings 6 package strings
7 7
8 import ( 8 import (
9 "unicode" 9 "unicode"
10 "unicode/utf8" 10 "unicode/utf8"
(...skipping 25 matching lines...) Expand all
36 // add the rest, if there is any 36 // add the rest, if there is any
37 if cur < len(s) { 37 if cur < len(s) {
38 a[i] = s[cur:] 38 a[i] = s[cur:]
39 } 39 }
40 return a 40 return a
41 } 41 }
42 42
43 // primeRK is the prime base used in Rabin-Karp algorithm. 43 // primeRK is the prime base used in Rabin-Karp algorithm.
44 const primeRK = 16777619 44 const primeRK = 16777619
45 45
46 // hashstr returns the hash and the appropriate multiplicative 46 // hashStr returns the hash and the appropriate multiplicative
47 // factor for use in Rabin-Karp algorithm. 47 // factor for use in Rabin-Karp algorithm.
48 func hashstr(sep string) (uint32, uint32) { 48 func hashStr(sep string) (uint32, uint32) {
49 hash := uint32(0) 49 hash := uint32(0)
50 for i := 0; i < len(sep); i++ { 50 for i := 0; i < len(sep); i++ {
51 hash = hash*primeRK + uint32(sep[i]) 51 hash = hash*primeRK + uint32(sep[i])
52 52 » }
53 » var pow, sq uint32 = 1, primeRK
54 » for i := len(sep); i > 0; i >>= 1 {
55 » » if i&1 != 0 {
56 » » » pow *= sq
57 » » }
58 » » sq *= sq
59 » }
60 » return hash, pow
61 }
62
63 // hashStrRev returns the hash of the reverse of sep and the
64 // appropriate multiplicative factor for use in Rabin-Karp algorithm.
65 func hashStrRev(sep string) (uint32, uint32) {
66 » hash := uint32(0)
67 » for i := len(sep) - 1; i >= 0; i-- {
68 » » hash = hash*primeRK + uint32(sep[i])
53 } 69 }
54 var pow, sq uint32 = 1, primeRK 70 var pow, sq uint32 = 1, primeRK
55 for i := len(sep); i > 0; i >>= 1 { 71 for i := len(sep); i > 0; i >>= 1 {
56 if i&1 != 0 { 72 if i&1 != 0 {
57 pow *= sq 73 pow *= sq
58 } 74 }
59 sq *= sq 75 sq *= sq
60 } 76 }
61 return hash, pow 77 return hash, pow
62 } 78 }
(...skipping 15 matching lines...) Expand all
78 } 94 }
79 return n 95 return n
80 case len(sep) > len(s): 96 case len(sep) > len(s):
81 return 0 97 return 0
82 case len(sep) == len(s): 98 case len(sep) == len(s):
83 if sep == s { 99 if sep == s {
84 return 1 100 return 1
85 } 101 }
86 return 0 102 return 0
87 } 103 }
88 » hashsep, pow := hashstr(sep) 104 » // Rabin-Karp search
105 » hashsep, pow := hashStr(sep)
89 h := uint32(0) 106 h := uint32(0)
90 for i := 0; i < len(sep); i++ { 107 for i := 0; i < len(sep); i++ {
91 h = h*primeRK + uint32(s[i]) 108 h = h*primeRK + uint32(s[i])
92 } 109 }
93 lastmatch := 0 110 lastmatch := 0
94 if h == hashsep && s[:len(sep)] == sep { 111 if h == hashsep && s[:len(sep)] == sep {
95 n++ 112 n++
96 lastmatch = len(sep) 113 lastmatch = len(sep)
97 } 114 }
98 for i := len(sep); i < len(s); { 115 for i := len(sep); i < len(s); {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 case n == 1: 149 case n == 1:
133 return IndexByte(s, sep[0]) 150 return IndexByte(s, sep[0])
134 case n == len(s): 151 case n == len(s):
135 if sep == s { 152 if sep == s {
136 return 0 153 return 0
137 } 154 }
138 return -1 155 return -1
139 case n > len(s): 156 case n > len(s):
140 return -1 157 return -1
141 } 158 }
142 » // Hash sep. 159 » // Rabin-Karp search
143 » hashsep, pow := hashstr(sep) 160 » hashsep, pow := hashStr(sep)
144 var h uint32 161 var h uint32
145 for i := 0; i < n; i++ { 162 for i := 0; i < n; i++ {
146 h = h*primeRK + uint32(s[i]) 163 h = h*primeRK + uint32(s[i])
147 } 164 }
148 if h == hashsep && s[:n] == sep { 165 if h == hashsep && s[:n] == sep {
149 return 0 166 return 0
150 } 167 }
151 for i := n; i < len(s); { 168 for i := n; i < len(s); {
152 h *= primeRK 169 h *= primeRK
153 h += uint32(s[i]) 170 h += uint32(s[i])
154 h -= pow * uint32(s[i-n]) 171 h -= pow * uint32(s[i-n])
155 i++ 172 i++
156 if h == hashsep && s[i-n:i] == sep { 173 if h == hashsep && s[i-n:i] == sep {
157 return i - n 174 return i - n
158 } 175 }
159 } 176 }
160 return -1 177 return -1
161 } 178 }
162 179
163 // LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s. 180 // LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s.
164 func LastIndex(s, sep string) int { 181 func LastIndex(s, sep string) int {
165 n := len(sep) 182 n := len(sep)
166 » if n == 0 { 183 » switch {
184 » case n == 0:
167 return len(s) 185 return len(s)
168 » } 186 » case n == 1:
169 » c := sep[0]
170 » if n == 1 {
171 // special case worth making fast 187 // special case worth making fast
188 c := sep[0]
172 for i := len(s) - 1; i >= 0; i-- { 189 for i := len(s) - 1; i >= 0; i-- {
173 if s[i] == c { 190 if s[i] == c {
174 return i 191 return i
175 } 192 }
176 } 193 }
177 return -1 194 return -1
178 » } 195 » case n == len(s):
179 » // n > 1 196 » » if sep == s {
180 » for i := len(s) - n; i >= 0; i-- { 197 » » » return 0
181 » » if s[i] == c && s[i:i+n] == sep { 198 » » }
199 » » return -1
200 » case n > len(s):
201 » » return -1
202 » }
203 » // Rabin-Karp search from the end of the string
204 » hashsep, pow := hashStrRev(sep)
205 » last := len(s) - n
206 » var h uint32
207 » for i := len(s) - 1; i >= last; i-- {
208 » » h = h*primeRK + uint32(s[i])
209 » }
210 » if h == hashsep && s[last:] == sep {
211 » » return last
212 » }
213 » for i := last - 1; i >= 0; i-- {
214 » » h *= primeRK
215 » » h += uint32(s[i])
216 » » h -= pow * uint32(s[i+n])
217 » » if h == hashsep && s[i:i+n] == sep {
182 return i 218 return i
183 } 219 }
184 } 220 }
185 return -1 221 return -1
186 } 222 }
187 223
188 // IndexRune returns the index of the first instance of the Unicode code point 224 // IndexRune returns the index of the first instance of the Unicode code point
189 // r, or -1 if rune is not present in s. 225 // r, or -1 if rune is not present in s.
190 func IndexRune(s string, r rune) int { 226 func IndexRune(s string, r rune) int {
191 switch { 227 switch {
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 // If s doesn't end with suffix, s is returned unchanged. 664 // If s doesn't end with suffix, s is returned unchanged.
629 func TrimSuffix(s, suffix string) string { 665 func TrimSuffix(s, suffix string) string {
630 if HasSuffix(s, suffix) { 666 if HasSuffix(s, suffix) {
631 return s[:len(s)-len(suffix)] 667 return s[:len(s)-len(suffix)]
632 } 668 }
633 return s 669 return s
634 } 670 }
635 671
636 // Replace returns a copy of the string s with the first n 672 // Replace returns a copy of the string s with the first n
637 // non-overlapping instances of old replaced by new. 673 // non-overlapping instances of old replaced by new.
674 // If old is empty, it matches at the beginning of the string
675 // and after each UTF-8 sequence, yielding up to k+1 replacements
676 // for a k-rune string.
638 // If n < 0, there is no limit on the number of replacements. 677 // If n < 0, there is no limit on the number of replacements.
639 func Replace(s, old, new string, n int) string { 678 func Replace(s, old, new string, n int) string {
640 if old == new || n == 0 { 679 if old == new || n == 0 {
641 return s // avoid allocation 680 return s // avoid allocation
642 } 681 }
643 682
644 // Compute number of replacements. 683 // Compute number of replacements.
645 if m := Count(s, old); m == 0 { 684 if m := Count(s, old); m == 0 {
646 return s // avoid allocation 685 return s // avoid allocation
647 } else if n < 0 || m < n { 686 } else if n < 0 || m < n {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 } 756 }
718 if r == tr { 757 if r == tr {
719 continue 758 continue
720 } 759 }
721 return false 760 return false
722 } 761 }
723 762
724 // One string is empty. Are both? 763 // One string is empty. Are both?
725 return s == t 764 return s == t
726 } 765 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b