Reverse words in Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: Playground - noun: a place where people can play | |
import UIKit | |
extension String { | |
private func reverseChars(chars: inout [String.Element], range: Range<Int>) { | |
guard chars.count > 1 else { | |
return | |
} | |
var down = range.lowerBound | |
var up = range.upperBound | |
while down < up { | |
(chars[down], chars[up]) = (chars[up], chars[down]) | |
down += 1 | |
up -= 1 | |
} | |
} | |
private func indicesOf(subString: String, searchArray: [String.Element]) -> [Int] { | |
// https://en.wikipedia.org/wiki/Knuth–Morris–Pratt_algorithm | |
var indices: [Int] = [] | |
let word = Array(subString) | |
var m = 0 | |
var i = 0 | |
while m + i < searchArray.count { | |
if word[i] == searchArray[m + i] { | |
if i == word.count - 1 { | |
indices.append(m) | |
m += i + 1 | |
i = 0 | |
} else { | |
i += 1 | |
} | |
} else { | |
m += 1 | |
i = 0 | |
} | |
} | |
return indices | |
} | |
func reversedWords() -> String { | |
var chars = Array(self) | |
let range = Range(0..<(chars.count-1)) | |
self.reverseChars(chars: &chars, range: range) | |
let indices = self.indicesOf(subString: " ", searchArray: chars) | |
var lower = 0 | |
for i in indices { | |
let range = Range(lower..<(i-1)) | |
self.reverseChars(chars: &chars, range: range) | |
lower = i+1 | |
} | |
let lastRange = Range(((indices.last!)+1)..<(chars.count-1)) | |
self.reverseChars(chars: &chars, range: lastRange) | |
return String(chars) | |
} | |
} | |
let str = "Stately, plump Buck Mulligan came from the stairhead, bearing a bowl of lather on which a mirror and a razor lay crossed." | |
let reversed = str.reversedWords() | |
print(reversed) // crossed. lay razor a and mirror a which on lather of bowl a bearing stairhead, the from came Mulligan Buck plump Stately, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment