Обмен переменных без временной
Условие
Напишите код, который меняет значения двух переменных местами без использования третьей (временной) переменной.
Пример
До: a = 5, b = 10 После: a = 10, b = 5
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение: Обмен переменных без временной
Описание задачи
Требуется реализовать обмен значений двух переменных без использования дополнительной временной переменной (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) | Только числа | Риск переполнения |
| XOR | O(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 — он:
- Самый читаемый и понятный
- Самый быстрый благодаря оптимизациям Python
- Самый безопасный — работает с любыми типами данных
- Идиоматичный — это стандарт Python
Другие методы (арифметика, XOR и т.д.) полезны для демонстрации алгоритмического мышления на интервью, но в реальном коде не используются. Для других языков (C, Java, C++) используйте временную переменную — это признанный стандарт.