Swift 4.2中Codility GenomicRangeQuery对此前缀和编码挑战的解释

时间:2019-03-14 10:33:21

标签: swift algorithm

当我感到困惑时,有人可以解释这个前缀和计算如何工作吗?我的意思是我理解它会创建一个包含字母的前缀和的Ints数组,但我不知道该怎么做?有人可以发表更幼稚的逻辑或一些解释吗?或者,也许是该MAP功能的较短版本,因为它全都令人困惑。

Link应对挑战,以防万一有人想看看它

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
}

2 个答案:

答案 0 :(得分:0)

prefixSumA计算从开始到每个给定索引的A数。关于prefixSumCprefixSumG也可以这样说。

例如,如果字符串S"CAGCCTA",我们将拥有:

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]

(请注意在开头插入零。)


这段代码:

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的当前值(它是数组中的最后一个值),对其进行递增,最后返回它({{1 }}。

s是一种奇特的方式,可以写成:

return (s += 1, s).1

整个块可以写得更简单:

s += 1
return s

对于var prefixSumA = [0] var countOfA = 0 prefixSumA += S.map { char in if char == "A" { countOfA += 1 } return countOfA } prefixSumC也可以这样做。

答案 1 :(得分:-1)

我尝试了这个,得到了62%。性能测试失败。

public func solution(_ S : inout String, _ P : inout [Int], _ Q : inout [Int]) -> [Int] {
// write your code in Swift 4.2.1 (Linux)

   var retArr = [Int]()
   var chrArr = [Character]()
   for chr in S {
       chrArr.append(chr)
   }


   for i in 0..<P.count {

       var minFactor = 4

       if P[i] - Q[i] == 0 {
           if chrArr[P[i]] == "A"{
               minFactor = 1
           }else if chrArr[P[i]] == "C"{
               minFactor = 2
           }else if chrArr[P[i]] == "G"{
               minFactor = 3
           }
       }else {
           for j in P[i]...Q[i] {

               if chrArr[j] == "A"{
                   minFactor = 1
                       break
               }else if chrArr[j] == "C"{
                       minFactor = 2
               }else if chrArr[j] == "G"{
                       if minFactor > 2 {
                           minFactor = 3
                           }
                   }
               }
       }

       retArr.append(minFactor)
   }

   return retArr

}