Swift 4.2中Codility GenomicRangeQuery对此前缀和编码挑战的解释 [英] Explanation of this prefix Sum Coding Challenge from Codility GenomicRangeQuery in Swift 4.2
问题描述
当我感到困惑时,有人可以解释这个前缀和计算如何工作吗?我的意思是我理解它会创建一个包含字母的前缀和的Ints数组,但我不知道该怎么做?有人可以发表更幼稚的逻辑或一些解释吗?也许是该MAP函数的较短版本,因为它全都令人困惑。
Could someone explain how this prefix sum calculation work as I am confused I mean I understand that it creates an array of Ints with the prefix-sums of the letters but I do not understand how? Could someone perhaps post a more naive logic or some explanation? Or perhaps a shorter version of that MAP function as it is all confusingly complicated.
链接以应对挑战,以防万一有人想看看
Link to the challenge just in case someone would like to have a look at it
public func solution(_ S : inout String, _ P : inout [Int], _ Q : inout [Int]) -> [Int] {
//The mapping below needs the explanation
var prefixSumA = S.map({ () -> (Character) -> Int in
var s = 0; return {
if $0 == "A" {
return (s += 1, s).1
}
return s
}
}())//until here
prefixSumA.insert(0, at: 0)
var prefixSumC = S.map({ () -> (Character) -> Int in
var s = 0; return {
if $0 == "C" {
return (s += 1, s).1
}
return s
}
}())
prefixSumC.insert(0, at: 0)
var prefixSumG = S.map({ () -> (Character) -> Int in
var s = 0; return {
if $0 == "G" {
return (s += 1, s).1
}
return s
}
}())
prefixSumG.insert(0, at: 0)
let iterations = min(P.count, Q.count)
var result = [Int]()
for i in 0...iterations - 1 {
let p = P[i]
let q = Q[i] + 1
if prefixSumA[q] - prefixSumA[p] > 0 {
result.append(1)
} else if prefixSumC[q] - prefixSumC[p] > 0 {
result.append(2)
} else if prefixSumG[q] - prefixSumG[p] > 0 {
result.append(3)
} else {
result.append(4)
}
}
return result
}
推荐答案
prefixSumA
计算从头到每个给定索引的 A
s的数量。关于 prefixSumC
和 prefixSumG
可以说相同。
prefixSumA
calculates the number of A
s from the start to every given index. The same can be said about prefixSumC
, and prefixSumG
.
例如,如果字符串 S
是 CAGCCTA
,我们将得到:
For example, if the string S
is "CAGCCTA"
, we'll have:
prefixSumA = [0, 0, 1, 1, 1, 1, 1, 2]
prefixSumC = [0, 1, 1, 1, 2, 3, 3, 3]
prefixSumG = [0, 0, 0, 1, 1, 1, 1, 1]
(请注意在开头插入零。)
(Notice the zero inserted at the beginning.)
此代码块:
var prefixSumA = S.map({ () -> (Character) -> Int in
var s = 0; return {
if $0 == "A" {
return (s += 1, s).1
}
return s
}
}())
prefixSumA.insert(0, at: 0)
返回一个闭包,如果字符是 A
,它将捕获 s
的当前值(是数组中的最后一个值),将其递增,最后返回( s
)。
returns a closure that, if the character is A
, would capture the current value of s
(which is the last value in the array), increment it, end return it (s
).
返回(s + = 1,s).1
是一种奇特的方式,可以这样写:
return (s += 1, s).1
is a fancy way, that could be written as:
s += 1
return s
整个块可以写得更简单:
The whole block can be written more simply:
var prefixSumA = [0]
var countOfA = 0
prefixSumA += S.map { char in
if char == "A" { countOfA += 1 }
return countOfA
}
对于 prefixSumC
和 prefixSumG
也可以这样做。
这篇关于Swift 4.2中Codility GenomicRangeQuery对此前缀和编码挑战的解释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!