@@ -33,65 +33,65 @@ Here's how you could write it in Swift:
3333``` swift
3434extension String {
3535func indexOf (pattern : String ) -> String .Index ? {
36- // Cache the length of the search pattern because we're going to
37- // use it a few times and it's expensive to calculate.
36+ // Cache the length of the search pattern because we're going to
37+ // use it a few times and it's expensive to calculate.
3838 let patternLength = pattern.characters .count
39- assert (patternLength > 0 )
40- assert (patternLength <= self .characters .count )
39+ assert (patternLength > 0 )
40+ assert (patternLength <= self .characters .count )
4141
42- // Make the skip table. This table determines how far we skip ahead
43- // when a character from the pattern is found.
42+ // Make the skip table. This table determines how far we skip ahead
43+ // when a character from the pattern is found.
4444 var skipTable = [Character : Int ]()
45- for (i, c) in pattern.characters .enumerate () {
46- skipTable[c] = patternLength - i - 1
45+ for (i, c) in pattern.characters .enumerated () {
46+ skipTable[c] = patternLength - i - 1
4747 }
4848
49- // This points at the last character in the pattern.
50- let p = pattern.endIndex . predecessor ( )
49+ // This points at the last character in the pattern.
50+ let p = index ( before : pattern.endIndex )
5151 let lastChar = pattern[p]
5252
53- // The pattern is scanned right-to-left, so skip ahead in the string by
54- // the length of the pattern. (Minus 1 because startIndex already points
55- // at the first character in the source string.)
56- var i = self .startIndex . advancedBy ( patternLength - 1 )
53+ // The pattern is scanned right-to-left, so skip ahead in the string by
54+ // the length of the pattern. (Minus 1 because startIndex already points
55+ // at the first character in the source string.)
56+ var i = index ( self .startIndex , offsetBy : patternLength - 1 )
5757
58- // This is a helper function that steps backwards through both strings
59- // until we find a character that doesn’t match, or until we’ve reached
60- // the beginning of the pattern.
58+ // This is a helper function that steps backwards through both strings
59+ // until we find a character that doesn’t match, or until we’ve reached
60+ // the beginning of the pattern.
6161 func backwards () -> String .Index ? {
62- var q = p
63- var j = i
64- while q > pattern.startIndex {
65- j = j. predecessor ( )
66- q = q. predecessor ( )
67- if self [j] != pattern[q] { return nil }
68- }
69- return j
62+ var q = p
63+ var j = i
64+ while q > pattern.startIndex {
65+ j = index ( before : j )
66+ q = index ( before : q )
67+ if self [j] != pattern[q] { return nil }
68+ }
69+ return j
7070 }
7171
72- // The main loop. Keep going until the end of the string is reached.
72+ // The main loop. Keep going until the end of the string is reached.
7373 while i < self .endIndex {
74- let c = self [i]
75-
76- // Does the current character match the last character from the pattern?
77- if c == lastChar {
78-
79- // There is a possible match. Do a brute-force search backwards.
80- if let k = backwards () { return k }
81-
82- // If no match, we can only safely skip one character ahead.
83- i = i.successor ()
84- } else {
85- // The characters are not equal, so skip ahead. The amount to skip is
86- // determined by the skip table. If the character is not present in the
87- // pattern, we can skip ahead by the full pattern length. However, if
88- // the character *is* present in the pattern, there may be a match up
89- // ahead and we can't skip as far.
90- i = i.advancedBy (skipTable[c] ?? patternLength)
91- }
74+ let c = self [i]
75+
76+ // Does the current character match the last character from the pattern?
77+ if c == lastChar {
78+
79+ // There is a possible match. Do a brute-force search backwards.
80+ if let k = backwards () { return k }
81+
82+ // If no match, we can only safely skip one character ahead.
83+ i = index (after : i)
84+ } else {
85+ // The characters are not equal, so skip ahead. The amount to skip is
86+ // determined by the skip table. If the character is not present in the
87+ // pattern, we can skip ahead by the full pattern length. However, if
88+ // the character *is* present in the pattern, there may be a match up
89+ // ahead and we can't skip as far.
90+ i = index (i, offsetBy : skipTable[c] ?? patternLength)
91+ }
92+ }
93+ return nil
9294 }
93- return nil
94- }
9595}
9696
9797```
0 commit comments