最近看到一题,反转一个字符串,比如 the sky is blue,反转之后就会变成 blue is sky the,也就是单词顺序反过来了,但是单词的字母顺序不会变。
其实这道题,方法有很多种,最简单的就是遍历,然后重新拼接。这个是最容易想到,而且也是最容易写。但是今天我们换种方法来实现它。
既然是反转字符串,我们首先给他来个完全反转,包括空格也会带过去。这样就变成了eulb si yks eht.到这里可能你们觉得咋越弄越复杂了。其实仔细看,你根据空格为节点,再来四个反转,不就变成了blue is sky the 吗?既然思路我们有了,那我们就来是试试看吧。
首先,既然我们要多次用到反转的方法,那我们先把这个方法封装起来。
func swapWords<T>(_ chars: inout [T], _ p: Int, _ q: Int) {
let temp = chars[p]
chars[p] = chars[q]
chars[q] = temp
}
好了,方法封装好了,那在我们逻辑中间试验一下吧。
我们先来解决第一步,完全反转。
func reversWords<T>(_ chars: inout [T], _ start: Int, _ end: Int){
var begin = start
var finish = end
while begin < finish {
swapWords(&chars, begin, finish)
begin = begin + 1
finish = finish - 1
}
}
我们先来试下看下这个方法能不能得到 eulb si yks eht。
func Reverse(_ str: String?) -> String? {
guard let s = str else {
return nil
}
var chars = Array(s)
reversWords(&chars, 0, chars.count - 1)
return String(chars)
}
查看打印结果,果然是我们想要的eulb si yks eht。
好了,接下来我们根据空格为节点反转,第一次反转eulb,第二次si。。。以此内推,不管他给的啥字符串我们都这么干。
好了,那我们开始干吧。
func Reverse(_ str: String?) -> String? {
guard let s = str else {
return nil
}
var chars = Array(s)
var start = 0
reversWords(&chars, 0, chars.count - 1)
for i in 0..<chars.count {
if i == chars.count - 1 || String(chars[i+1]) == " " {
reversWords(&chars, start, i)
start = i + 2
print("\(String(chars))----第\(i)次打印的结果")
}
}
return String(chars)
}
print(Reverse(s)!)
打印结果出来了:blue is sky the.我们的结果得到了。
为了确保是对的,我们再来验证一个长一点的,然后结束吧。比如,hello mi fan are you ok,这句耳熟能详的英文吧,😄,lets go!图片发不出来了,结果是对的,一直提示字数超过限制,感兴趣的话自己去试试吧。