Есть ли способ экспоненциального увеличения в Swift? - PullRequest
1 голос
/ 03 апреля 2019

Я пытаюсь написать цикл for, где мне нужно увеличивать экспоненциально.Я использую функцию stride, но она не будет работать.Вот код C ++, я пытаюсь написать быструю версию.

for (int m = 1; m <= high - low; m = 2*m){}

Можете ли вы помочь мне написать этот код в быстрой версии?

Ответы [ 4 ]

6 голосов
/ 03 апреля 2019

Цикл while - это, возможно, самое простое решение, но есть альтернатива:

for m in sequence(first: 1, next: { 2 * $0 }).prefix(while: { $0 <= high - low }) {
    print(m)
}

sequence() (лениво) генерирует последовательность 1, 2, 4, ... и prefix(while:) ограничивает эту последовательность заданным диапазоном.

Небольшое преимущество этого подхода заключается в том, что m объявляется только внутри цикла (так что его нельзя использовать позже случайно), и это константа , так что она не может быть случайно изменена внутри петли.

3 голосов
/ 03 апреля 2019

В Swift нет петли for, но вы можете добиться того же результата с помощью базовой while петли

var m = 1                // initializer
while m <= high - low {  // condition
    ...
    m *= 2               // iterator
}
1 голос
/ 03 апреля 2019

На основании @ ответа MartinR , только улучшение - читаемость разговора:

// Helper function declaration
func forgen<T>(
    _ initial: T, // What we start with
    _ condition: @escaping (T) throws -> Bool, // What to check on each iteration
    _ change: @escaping (T) -> T?, // Change after each iteration
    _ iteration: (T) throws -> Void // Where actual work happens
    ) rethrows
{
    return try sequence(first: initial, next: change).prefix(while: condition).forEach(iteration)
}

// Usage:
forgen(1, { $0 <= high - low }, { 2 * $0 }) { m in
    print(m)
}
// Almost like in C/C++ code
0 голосов
/ 03 апреля 2019

Вот решение, использующее for:

let n = Int(log(Double(high - low))/log(2.0)) 
var m = 1
for p in 1...n {
    print("m =", m)
    ...
    m = m << 1
}

(Предположим, что high - low больше 2)

...