Цикл for, основанный на экспоненциальном увеличении

Я пытаюсь реализовать сортировку по основанию в Swift (строго от скуки). До сих пор я основывал свою работу на методе C/C++, найденном здесь.

По большей части все работает так, как я и ожидал, за исключением одного цикла for, который доставляет мне проблемы.

for (int exp = 1; max / exp > 0; exp *= 10)

Swift больше не поддерживает циклы в стиле C, так что это не сработает. Я пытался воссоздать цикл, используя несколько подходов, включая этот:

var exp: Int = 1
for _ in (1..<(max / exp)).reversed()
{
    //My code
    exp = exp * 10
}

Проблема здесь в том, что Int не может содержать размер exp после нескольких итераций цикла. Поскольку исходное определение цикла прекрасно работает в Objective-C, я считаю, что мой полный подход ошибочен, но я не вижу, где именно.

Какие-нибудь мысли?


person William Smith    schedule 29.10.2016    source источник
comment
Ваше условие оценивается только один раз в вашей версии Swift со значением 1. Вместо этого используйте цикл while.   -  person Sulthan    schedule 30.10.2016
comment
@MartinR согласился, особенно с вашим дополнением без переполнения Int.max в конце вашего ответа.   -  person dfrib    schedule 30.10.2016
comment
Обратите внимание, что ваш код C не работает правильно для чисел, близких к INT_MAX: exp *= 10 может переполниться, даже если max/exp > 0 (что эквивалентно exp <= max для положительных чисел).   -  person Martin R    schedule 30.10.2016
comment
На основе решения в цели обмана, например. exp = sequence(first: exp, next: { $0 <= max/10 && 0 < max/$0 ? $0 * 10 : nil}).reduce(0) { $1 } должен безопасно решить ваше преобразование цикла C-> Swift.   -  person dfrib    schedule 30.10.2016
comment
@MartinR, кстати, знаете ли вы более изящный способ получить последний элемент (возможно, бесконечной) последовательности? (Скажем, нас интересует только последнее, как в этом примере). Нам нужно будет пройти по элементам один за другим, мне интересно, есть ли лучший выбор, чем решение reduce выше (единственная альтернатива, которую я мог придумать, была .map { $0 }.last ?? 0).   -  person dfrib    schedule 30.10.2016
comment
@dfri: нет, не знаю. ОП прямо не указал, что требуется только последнее значение. Если это так, то я бы, вероятно, использовал цикл while, аналогичный приведенному ниже ответу: var exp = 1; while 10 * exp <= max { exp *= 10 }.   -  person Martin R    schedule 30.10.2016
comment
@MartinR Хорошо, спасибо! Незначительная подсказка w.r.t. ninja-edit: в этом примере с экспоненциальным ростом этот цикл while, вероятно, должен использовать условие exp <= max/10 (или переполнение для достаточно больших max значений, поскольку 10 * exp проверяется один раз даже для неудачного теста, > max).   -  person dfrib    schedule 30.10.2016
comment
@dfri Да, это то, что я имел в виду.   -  person Martin R    schedule 30.10.2016
comment
Я понимаю, что эта тема закрыта или скоро будет закрыта, но для записи я использовал очень простой цикл while, как было предложено, и он отлично сработал. Думаю, после нескольких часов изучения алгоритмов сортировки я потерял из виду лес за деревьями. Спасибо, парни!   -  person William Smith    schedule 30.10.2016