在 Swift 中有更容易阅读的 运行-length 编码吗?
Any easier to read run-length Encoding in Swift?
任何人都可以在 swift 中编写 运行-length 编码代码,比下面的代码更容易阅读,或者至少解释一下我从 rosettecode.org 得到的代码吗?
这是输入&输出和代码
// "WWWBWW" -> [(3, W), (1, B), (2, W)]
func encode(input: String) -> [(Int, Character)] {
return input.characters.reduce([(Int, Character)]()) {
if [=12=].last?.1 == { var r = [=12=]; r[r.count - 1].0++; return r }
return [=12=] + [(1, )]
}
}
希望这能让你更容易理解。
func encode2(input: String) -> [(Int, Character)] {
var result = [(Int, Character)]()
input.forEach { char in
if result.last?.1 == char {
result[result.count - 1].0 += 1
} else {
result.append((1, char))
}
}
return result
}
如果你改用 reduce(into:) 会更容易理解:
func encode(input: String) -> [(Int, Character)] {
input.reduce(into: [(Int, Character)]()) {
// if the second element of the last tuple of the result is equal to the current element (character) of the collection
if [=10=].last?.1 == {
// increase the first element of the last tuple tuple of the result
[=10=][[=10=].index(before: [=10=].endIndex)].0 += 1
} else {
// otherwise add a new tuple with a value of 1 and the current element (character) to the result
[=10=] += CollectionOfOne((1, ))
}
}
}
encode(input: "WWWBWW") // [(.0 3, .1 "W"), (.0 1, .1 "B"), (.0 2, .1 "W")]
您还可以扩展 Collection 并实现一个泛型 method/property
extension Collection where Element: Equatable {
var groupped: [(Int, Element)] {
reduce(into: []) {
if [=12=].last?.1 == {
[=12=][[=12=].index(before: [=12=].endIndex)].0 += 1
} else {
[=12=] += CollectionOfOne((1, ))
}
}
}
}
"WWWBWW".groupped // [(.0 3, .1 "W"), (.0 1, .1 "B"), (.0 2, .1 "W")]
我用下面的方法解决了这个任务,可能有人更清楚:
func compress(input: String) -> [(Int, Character)] {
var output = [(Int, Character)]()
var count: Int = 1 // count of repeated characters
var i = 0
while i < input.count { // select the current character
var j = i + 1
while j < input.count &&
input[input.index(input.startIndex, offsetBy: i)] == input[input.index(input.startIndex, offsetBy: j)] { // count repeated charactes followed the current one
count += 1
j += 1
}
output.append((count, input[input.index(input.startIndex, offsetBy: i)]))
i = j // move index for the current character to the index of the last repeated one
count = 1 // reset count
}
return output
}
任何人都可以在 swift 中编写 运行-length 编码代码,比下面的代码更容易阅读,或者至少解释一下我从 rosettecode.org 得到的代码吗? 这是输入&输出和代码
// "WWWBWW" -> [(3, W), (1, B), (2, W)]
func encode(input: String) -> [(Int, Character)] {
return input.characters.reduce([(Int, Character)]()) {
if [=12=].last?.1 == { var r = [=12=]; r[r.count - 1].0++; return r }
return [=12=] + [(1, )]
}
}
希望这能让你更容易理解。
func encode2(input: String) -> [(Int, Character)] {
var result = [(Int, Character)]()
input.forEach { char in
if result.last?.1 == char {
result[result.count - 1].0 += 1
} else {
result.append((1, char))
}
}
return result
}
如果你改用 reduce(into:) 会更容易理解:
func encode(input: String) -> [(Int, Character)] {
input.reduce(into: [(Int, Character)]()) {
// if the second element of the last tuple of the result is equal to the current element (character) of the collection
if [=10=].last?.1 == {
// increase the first element of the last tuple tuple of the result
[=10=][[=10=].index(before: [=10=].endIndex)].0 += 1
} else {
// otherwise add a new tuple with a value of 1 and the current element (character) to the result
[=10=] += CollectionOfOne((1, ))
}
}
}
encode(input: "WWWBWW") // [(.0 3, .1 "W"), (.0 1, .1 "B"), (.0 2, .1 "W")]
您还可以扩展 Collection 并实现一个泛型 method/property
extension Collection where Element: Equatable {
var groupped: [(Int, Element)] {
reduce(into: []) {
if [=12=].last?.1 == {
[=12=][[=12=].index(before: [=12=].endIndex)].0 += 1
} else {
[=12=] += CollectionOfOne((1, ))
}
}
}
}
"WWWBWW".groupped // [(.0 3, .1 "W"), (.0 1, .1 "B"), (.0 2, .1 "W")]
我用下面的方法解决了这个任务,可能有人更清楚:
func compress(input: String) -> [(Int, Character)] {
var output = [(Int, Character)]()
var count: Int = 1 // count of repeated characters
var i = 0
while i < input.count { // select the current character
var j = i + 1
while j < input.count &&
input[input.index(input.startIndex, offsetBy: i)] == input[input.index(input.startIndex, offsetBy: j)] { // count repeated charactes followed the current one
count += 1
j += 1
}
output.append((count, input[input.index(input.startIndex, offsetBy: i)]))
i = j // move index for the current character to the index of the last repeated one
count = 1 // reset count
}
return output
}