Методы переворота числа: от простого к сложному

Раздел: Алгоритмы -> Работа с цифрами

Переворот числа: задачи и решения

Перестановка цифр числа в обратном порядке (реверс числа) – распространённая алгоритмическая задача. В Python существует несколько подходов, различающихся по скорости, читаемости и устойчивости к краевым случаям. Ниже представлены основные варианты, начиная с наиболее эффективного и заканчивая альтернативными.

Как сделать реверс числа за одну строку без циклов?

Наиболее быстрый и компактный способ – преобразовать число в строку, развернуть её с помощью среза [::-1] и преобразовать обратно в целое число. Этот метод работает для любых неотрицательных целых чисел и не требует импорта дополнительных модулей.

def reverse_num(num):
    return int(str(num)[::-1])

вторая цифра числа python (получение второй цифры числа в python)

Пример вызова: reverse_num(12345) вернёт 54321.

Потенциальная проблема:

Если число оканчивается на нули (например, 1200), при обратном преобразовании лидирующие нули теряются – результат будет 21, а не 0021. Для многих прикладных задач это корректно, так как цифровое представление 0021 эквивалентно 21. Если же требуется сохранить количество разрядов (например, для вывода с ведущими нулями), следует работать со строкой без преобразования в int.

Как развернуть число без использования строк, только арифметикой?

Классический математический способ: пока исходное число не станет нулём, извлекать последнюю цифру через остаток от деления на 10, добавлять её к результату (умножив результат на 10) и отбрасывать последнюю цифру целочисленным делением на 10.

def reverse_math(num):
    reversed_num = 0
    while num > 0:
        reversed_num = reversed_num * 10 + num % 10
        num //= 10
    return reversed_num

Python срез числа (извлечение части числа (срез цифр) в python)

Пример: reverse_math(4567) → 7654.

Типичные ошибки и их решение:

  • Отрицательные числа: цикл не выполнится, так как num > 0 ложно. Решение: сохранить знак и работать с абсолютным значением.
  • Числа, оканчивающиеся на ноль: как и в строковом методе, лидирующие нули теряются (120 → 21). Если требуется сохранить точное количество цифр, нужно запоминать количество разрядов или использовать строки.
  • Переполнение: в Python целые числа не ограничены, но в других языках результат может выйти за границы типа. Для Python проблема неактуальна.

Как реализовать рекурсивное обращение числа?

Рекурсия делает код элегантным, но менее производительным из-за глубины стека. Алгоритм: базовый случай – число меньше 10, возвращаем его; иначе возвращаем (num % 10) * 10^{len-1} + reverse_rec(num // 10).

def reverse_rec(num):
    if num < 10:
        return num
    import math
    digits = int(math.log10(num)) + 1
    return (num % 10) * (10 ** (digits - 1)) + reverse_rec(num // 10)

число в обратном порядке python (переворот числа (обратный порядок цифр) в python)

Пример: reverse_rec(789) → 987.

Проблемы:

  • Ограничение глубины рекурсии (по умолчанию ~1000). Для больших чисел вызовет RecursionError. Решение: увеличить лимит через sys.setrecursionlimit() или отказаться от рекурсии.
  • Логарифмическая операция log10 может давать неточности для степеней 10 (например, 1000 → log10(1000)=3, но из-за ошибок с плавающей точкой возможно 2.999...). Лучше использовать цикл для подсчёта разрядов.
  • Отрицательные числа и нули требуют дополнительной обработки.

Как учесть знак числа при перевороте?

Если число может быть отрицательным, стандартные методы нужно модифицировать: запомнить знак, работать с абсолютным значением, затем применить знак к результату. Для строкового метода достаточно убрать знак, развернуть цифры и вернуть знак обратно (если результат не ноль).

def reverse_signed(num):
    if num == 0:
        return 0
    sign = -1 if num < 0 else 1
    abs_rev = int(str(abs(num))[::-1])
    return sign * abs_rev

сколько цифр в числе python (подсчёт количества цифр в числе в python)

Для математического метода: while abs_num > 0.

Особенность:

Обратное число может быть настолько большим, что не поместится в стандартные типы, но Python справится. Однако в некоторых задачах (например, LeetCode) требуется возвращать 0 при переполнении 32-битного знакового целого. В таких случаях после реверса проверяют границы -2^31 ... 2^31-1.

Как сохранить ведущие нули при реверсе?

Если требуется получить строку с ведущими нулями (например, число 1200 → '0021'), нельзя преобразовывать результат в int. Нужно развернуть строковое представление и вернуть строку. Если число поступило как целое, можно добавить недостающие нули слева.

def reverse_keep_zeros(num):
    s = str(num)
    return s[::-1]

Важное замечание:

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

Выбор метода зависит от контекста: строковый – для скорости и простоты, математический – для демонстрации алгоритмического мышления (часто используется на собеседованиях), рекурсивный – для учебных целей. Обработка знаков и нулей должна быть предусмотрена отдельно.

Дополнительные примеры и нестандартные ситуации

Как развернуть число с помощью списка цифр и reduce?

Функциональный подход: преобразовать число в список цифр, развернуть его (или использовать reduce для построения числа).

Пример
from functools import reduce

def reverse_reduce(num):
    digits = [int(d) for d in str(num)]
    return reduce(lambda acc, d: acc * 10 + d, reversed(digits))

Результат для 3456: 6543.

Как обработать число с плавающей точкой (дробную часть)?

Реверс дробного числа может означать переворот целой части или всей записи. Для полного реверса (включая точку) строка преобразуется целиком, но точка остаётся на позиции.

Пример
def reverse_float(num):
    s = str(num)
    if '.' in s:
        parts = s.split('.')
        rev_int = parts[0][::-1]
        rev_frac = parts[1][::-1]
        return float(rev_int + '.' + rev_frac)
    else:
        return float(s[::-1])

Пример: reverse_float(12.34) → 43.21 (обратите внимание: 12.34 → '43.21' → 43.21). Но при преобразовании в float ведущие нули справа от точки отбрасываются (12.30 → '03.21' → 3.21).

Как развернуть число, работая с двоичным или шестнадцатеричным представлением?

Для не десятичных систем счисления можно преобразовать в строку с нужным основанием, развернуть и вернуть обратно.

Пример
def reverse_base(num, base=2):
    # Преобразуем в строку заданной системы
    digits = '0123456789ABCDEF'
    if num == 0:
        return '0'
    s = ''
    n = num
    while n > 0:
        s = digits[n % base] + s
        n //= base
    # Переворот
    rev_s = s[::-1]
    # Обратно в число
    return int(rev_s, base)

Пример: reverse_base(13, 16) : 1310 = 0xD → реверс 'D0' → 0xD0 = 208. Если нужна только строка, можно вернуть rev_s.

Как развернуть очень большое число (сотни цифр) эффективно?

Для длинных чисел математический метод медленнее строкового из-за множества операций умножения и деления. Лучше использовать строковый метод, который в CPython реализован на C и работает быстро. Исследование времени:

Пример
import time
num = 10**1000  # число из 1001 цифры
start = time.perf_counter()
rev_str = int(str(num)[::-1])
end = time.perf_counter()
print(f"Строковый метод: {end-start:.6f} сек")

Результат: ~0.0003 сек. Аналогичный математический цикл займёт в десятки раз больше.

Строковый метод: 0.000312 сек

Как обработать число, содержащее символы (например, знак минус и ведущие нули)?

Если входные данные – строка, представляющая число (например, "-00120"), можно развернуть всю строку, сохранив знак (если он есть) и переставив символы правильно (знак остаётся в начале).

Пример
def reverse_string_number(s):
    if not s:
        return s
    if s[0] in '+-':
        sign = s[0]
        body = s[1:]
    else:
        sign = ''
        body = s
    # Переворот тела, затем добавление знака
    rev_body = body[::-1]
    # Удаление ведущих нулей (если нужно сохранить чистый вид)
    rev_body_stripped = rev_body.lstrip('0') or '0'
    return sign + rev_body_stripped

Пример: reverse_string_number("-00120") → "-2100" (с сохранением знака и удалением лишних нулей).

Как развернуть число, не используя встроенные функции строк (только арифметику и списки)?

Можно извлекать цифры в массив, затем собрать число задом наперёд.

Пример
def reverse_math_list(num):
    n = abs(num)
    digits = []
    while n > 0:
        digits.append(n % 10)
        n //= 10
    rev = 0
    for d in digits:
        rev = rev * 10 + d
    return rev if num >= 0 else -rev

Этот вариант близок к чистому математическому, но с промежуточным списком, что может быть полезно для последующей обработки цифр.

Как создать декоратор для проверки переполнения при реверсе 32-битного числа?

В задачах (например, LeetCode 7) требуется вернуть 0, если результат не помещается в 32-битное знаковое целое. Декоратор делает проверку универсальной.

Пример
def check_overflow_32bit(func):
    def wrapper(num):
        res = func(num)
        if res < -2**31 or res > 2**31 - 1:
            return 0
        return res
    return wrapper

@check_overflow_32bit
def reverse_32bit(num):
    sign = -1 if num < 0 else 1
    rev = int(str(abs(num))[::-1])
    return sign * rev

Пример: reverse_32bit(1534236469) → 0, так как обратное число 9646324351 больше 2^31-1.

Итог: каждый метод имеет свою нишу. Для обычных задач достаточно int(str(num)[::-1]) с доработкой знака. Для точного контроля над ведущими нулями – работайте со строками. Для демонстрации алгоритмов – математический или рекурсивный способы.

Переворот числа (обратный порядок цифр) в Python - comments

En
число в обратном порядке python (python)