← Назад к вопросам

Обмен переменных без временной

2.0 Middle🔥 131 комментариев
#Теория тестирования

Условие

Напишите код, который меняет значения двух переменных местами без использования третьей (временной) переменной.

Пример

До: a = 5, b = 10 После: a = 10, b = 5

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Решение: Обмен переменных без временной

Описание задачи

Требуется реализовать обмен значений двух переменных без использования дополнительной временной переменной (swap without temporary variable). Хотя в Python существует встроенный способ (a, b = b, a), эта задача демонстрирует глубокое понимание работы памяти, типов данных и различных трюков программирования. Классическая задача на интервью, которая встречается во многих языках программирования и показывает творческое мышление разработчика.

Решение на Python

def swap_variables(a, b):
    """
    Обменивает значения двух переменных без временной переменной.
    Pythonic способ с распаковкой кортежей.
    
    Args:
        a: первая переменная
        b: вторая переменная
    
    Returns:
        кортеж (новое значение a, новое значение b)
    """
    # В Python это самый читаемый способ
    return b, a

# Использование:
a, b = 5, 10
a, b = swap_variables(a, b)
print(a, b)  # 10 5

Альтернативные подходы

1. Арифметическое сложение (для чисел)

def swap_arithmetic(a, b):
    """
    Использует арифметику для обмена.
    Работает только для чисел!
    Внимание: риск переполнения при очень больших числах.
    """
    a = a + b      # a теперь содержит сумму
    b = a - b      # b получает исходное значение a
    a = a - b      # a получает исходное значение b
    
    return a, b

2. Использование XOR (побитовая операция)

def swap_xor(a, b):
    """
    Использует побитовую операцию XOR.
    Работает только для целых чисел!
    """
    a = a ^ b  # XOR
    b = a ^ b  # Восстанавливает исходное b
    a = a ^ b  # Восстанавливает исходное a
    
    return a, b

# Альтернативный компактный вариант:
def swap_xor_compact(a, b):
    a, b = a ^ b, a ^ (a ^ b)
    return a, b

3. Умножение и деление (для ненулевых чисел)

def swap_mult_div(a, b):
    """
    Использует умножение и деление.
    ОПАСНО: риск деления на ноль и переполнения!
    """
    if b == 0:
        raise ValueError('b не может быть нулём')
    
    a = a * b
    b = a // b
    a = a // b
    
    return a, b

4. С использованием списка

def swap_list(a, b):
    """
    Использует список как хранилище.
    Работает для любых типов данных.
    """
    lst = [a]  # Сохраняем a в список
    a = b
    b = lst[0]
    
    return a, b

5. С использованием словаря

def swap_dict(a, b):
    """
    Использует словарь.
    Творческий, но не практичный способ.
    """
    d = {'temp': a}
    a = b
    b = d['temp']
    
    return a, b

6. С использованием распаковки (самый Pythonic)

def swap_pythonic(a, b):
    """
    Самый читаемый и эффективный способ в Python.
    Использует распаковку кортежей.
    """
    # Это основной способ, рекомендуемый в Python
    return b, a

# Использование:
a, b = 5, 10
a, b = b, a
print(a, b)  # 10 5

7. С использованием функции (для изменения на месте)

def swap_inplace(variables, index1, index2):
    """
    Обменивает элементы в списке без временной переменной.
    """
    variables[index1], variables[index2] = variables[index2], variables[index1]
    return variables

# Использование:
values = [5, 10]
values = swap_inplace(values, 0, 1)
print(values)  # [10, 5]

Тестовые примеры

import unittest

class TestSwapVariables(unittest.TestCase):
    
    def test_basic_integers(self):
        # Базовый случай из условия
        a, b = 5, 10
        a, b = swap_variables(a, b)
        assert a == 10 and b == 5
    
    def test_negative_numbers(self):
        # Отрицательные числа
        a, b = -5, 10
        a, b = swap_variables(a, b)
        assert a == 10 and b == -5
    
    def test_zeros(self):
        # С нулями
        a, b = 0, 10
        a, b = swap_variables(a, b)
        assert a == 10 and b == 0
    
    def test_both_zeros(self):
        # Оба нуля
        a, b = 0, 0
        a, b = swap_variables(a, b)
        assert a == 0 and b == 0
    
    def test_same_values(self):
        # Одинаковые значения
        a, b = 5, 5
        a, b = swap_variables(a, b)
        assert a == 5 and b == 5
    
    def test_strings(self):
        # Строки (работает с любыми типами!)
        a, b = 'hello', 'world'
        a, b = swap_variables(a, b)
        assert a == 'world' and b == 'hello'
    
    def test_floats(self):
        # Числа с плавающей точкой
        a, b = 3.14, 2.71
        a, b = swap_variables(a, b)
        assert a == 2.71 and b == 3.14
    
    def test_mixed_types(self):
        # Смешанные типы
        a, b = 42, 'text'
        a, b = swap_variables(a, b)
        assert a == 'text' and b == 42
    
    def test_large_numbers(self):
        # Большие числа
        a, b = 10**100, 10**200
        a, b = swap_variables(a, b)
        assert a == 10**200 and b == 10**100
    
    def test_arithmetic_method(self):
        # Арифметический способ
        a, b = 5, 10
        a, b = swap_arithmetic(a, b)
        assert a == 10 and b == 5
    
    def test_xor_method(self):
        # XOR способ
        a, b = 5, 10
        a, b = swap_xor(a, b)
        assert a == 10 and b == 5
    
    def test_xor_with_zero(self):
        # XOR с нулём
        a, b = 0, 10
        a, b = swap_xor(a, b)
        assert a == 10 and b == 0
    
    def test_xor_same_values(self):
        # XOR с одинаковыми значениями
        a, b = 5, 5
        a, b = swap_xor(a, b)
        assert a == 5 and b == 5
    
    def test_xor_with_negative(self):
        # XOR с отрицательными (осторожно!)
        a, b = -5, 10
        a, b = swap_xor(a, b)
        assert a == 10 and b == -5
    
    def test_list_method(self):
        # Способ со списком
        a, b = 5, 10
        a, b = swap_list(a, b)
        assert a == 10 and b == 5

class TestSwapPerformance(unittest.TestCase):
    
    def test_all_methods_identical_result(self):
        # Все методы должны давать одинаковый результат
        test_cases = [(5, 10), (-5, 10), (0, 0), (100, 200)]
        
        for a, b in test_cases:
            result_pythonic = swap_variables(a, b)
            result_arithmetic = swap_arithmetic(a, b)
            result_xor = swap_xor(a, b)
            
            assert result_pythonic == result_arithmetic == result_xor

Анализ методов

МетодВременная сложностьПространственная сложностьРаботает для всех типовПримечание
Pythonic (a, b = b, a)O(1)O(1)ДаРекомендуется
АрифметикаO(1)O(1)Только числаРиск переполнения
XORO(1)O(1)Только целыеСложнее понять
Умножение/делениеO(1)O(1)Только ненулевыеОПАСНО
СписокO(1)O(1)ДаНе практично

Почему Python способ лучше?

# Python создаёт кортеж (b, a) ПЕРЕД присваиванием
# Поэтому исходные значения не теряются
a, b = b, a

# Эквивалент:
temp_tuple = (b, a)  # Кортеж создаётся первым
a = temp_tuple[0]     # Потом распаковывается
b = temp_tuple[1]     # Настоящей временной переменной НЕТ

Применение в QA Automation

  • Функциональное тестирование — проверка алгоритмов обмена данных
  • Тестирование обработки данных — проверка корректности манипуляций с переменными
  • Граничные случаи — нули, отрицательные, большие числа, смешанные типы
  • Performance тестирование — сравнение скорости разных методов
  • Обучение — демонстрация различных подходов программирования

Рекомендация

Для стандартного использования в Python всегда используйте Pythonic способ a, b = b, a — он:

  1. Самый читаемый и понятный
  2. Самый быстрый благодаря оптимизациям Python
  3. Самый безопасный — работает с любыми типами данных
  4. Идиоматичный — это стандарт Python

Другие методы (арифметика, XOR и т.д.) полезны для демонстрации алгоритмического мышления на интервью, но в реальном коде не используются. Для других языков (C, Java, C++) используйте временную переменную — это признанный стандарт.