swift maximum consecutive positive numbers

2019-02-24 02:12发布

问题:

How to count maximum consecutive positive numbers using closures?

var numbers = [1,3,4,-1,-2,5,2,-2,-3,-4,5]
//in this case it should be 3

print(numbers.reduce(0, { $1 > 0 ? $0 + 1 : $0 } ))//this counts total positive numbers

回答1:

Update: Simpler solution: Split the array into slices of positive elements, and determine the maximal slice length:

let  numbers = [1,3,4,-1,-2,5,2,-2,-3,-4,5]
let maxConsecutive = numbers.split(whereSeparator: { $0 <= 0 }).map { $0.count }.max()!
print(maxConsecutive) // 3

Old answer:) Using the ideas from Swift running sum:

let  numbers = [1,3,4,-1,-2,5,2,-2,-3,-4,5]

let maxConsecutive = numbers.map({
    () -> (Int) -> Int in var c = 0; return { c = $0 > 0 ? c + 1 : 0; return c }
}()).max()!

Here map() maps each array element to the count of consecutive positive numbers up to the elements position, in this case

[1, 2, 3, 0, 0, 1, 2, 0, 0, 0, 1]

The transformation is created as an "immediately evaluated closure" to capture a variable c which holds the current number of consecutive positive numbers. The transformation increments or resets c, and returns the updated value.

If the array is possibly large then change it to

let maxConsecutive = numbers.lazy.map( ... ).max()!

so that the maximum run length is determined without creating an intermediate array.



回答2:

var numbers = [1, 3, 4, -1, -2, 5, 2, -2, -3, -4, 5]

let result = numbers.reduce((current: 0, max: 0)) { result, number in
    var value = result

    if number > 0 {
        value.current += 1
        value.max = max(value.current, value.max)
    } else {
        value.current = 0
    }

    return value
}



result.max


回答3:

var currentResult = 0
var maxResult = 0
for i in numbers {
    currentResult = i > 0 ? currentResult + 1 : 0
    if maxResult < currentResult {
       maxResult = currentResult
    }
}
print(maxResult)

Solution without closures



回答4:

Generating subsequences:

let numbers = [1,3,4,-1,-2,5,2,-2,-3,-4,5]
let subsequences: [[Int]] = numbers.reduce(into: []) { (result, number) in
    guard
        var currentSequence = result.last,
        let lastNumber = currentSequence.last
    else {
        result = [[number]]
        return
    }

    if number == lastNumber + 1 {
        currentSequence.append(number)
        result.removeLast()
        result.append(currentSequence)
    } else {
        result.append([number])
    }
}
let longest = subsequences.max { $0.count < $1.count }
print(subsequences)
print("Longest subsequence: \(longest)")
print("Longest length: \(longest?.count)")