J. Слияние

Напишите функцию merge, которая принимает два отсортированных по возрастанию кортежа целых чисел, а возвращает один из всех переданных чисел.

Примечание

Ваше решение должно содержать только функции.
В решении не должно быть вызовов требуемых функций.
В этой задаче отключены стандартные сортировки

Пример

Ввод

result = merge((1, 2), (3, 4, 5))

Вывод

result = (1, 2, 3, 4, 5)

Ввод

result = merge((7, 12), (1, 9, 50))

Вывод

result = (1, 7, 9, 12, 50)

Решение

Задание представляет собой часть одного из самых эффективных алгоритмов сортировки – сортировка слиянием. Нам нужно написать алгоритм заключительной части – слияние двух отсортированных списков.

Решение достаточно простое.

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

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

Ниже представлено два решения – первое интуитивно более простое, с удалением использованных элементов из списка. Это решение очень наглядное, но неэффективное с точки зрения производительности, так как удаление элементов из списков во-первых портит входные данные, а во-вторых операция удаления первого элемента списка относительно дорогая, c точки зрения использования вычислительных ресурсов, операция.

Вопреки заявлениям Яндекса, по состоянию на 16 января 2024 года для решения задачи можно воспользоваться методом sort(), что напрочь убивает всю пользу от самостоятельного решения этой задачи.

Посмотреть код

Решение

Python
# Вариант с удалением элементов из списков

def merge(sequence_1, sequence_2):
    queue_1 = list(sequence_1)
    queue_2 = list(sequence_2)
    sequence = []
    while queue_1 and queue_2:
        if queue_1[0] > queue_2[0]:
            sequence.append(queue_2.pop(0))
        else:
            sequence.append(queue_1.pop(0))
    sequence.extend(queue_1)
    sequence.extend(queue_2)
    return tuple(sequence)

Решение

Python
# Вариант с индексами элементов списков

def merge(sequence_1, sequence_2):
    pos1 = 0
    pos2 = 0
    sequence = []
    while pos1 < len(sequence_1) and pos2 < len(sequence_2):
        if sequence_1[pos1] > sequence_2[pos2]:
            sequence.append(sequence_2[pos2])
            pos2 += 1
        else:
            sequence.append(sequence_1[pos1])
            pos1 += 1
    sequence.extend(sequence_1[pos1:])
    sequence.extend(sequence_2[pos2:])
    return tuple(sequence)
Подписаться
Уведомить о
guest
10 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
nmalkam
03.01.2024 08:34

def merge(tuple1: tuple, tuple2: tuple) -> tuple:
“””Слияние”””
lists = [i for i in tuple1]
lists.extend([i for i in tuple2])
lists.sort()
tuple_out = tuple(lists)
return tuple_out
у меня этот код прошел, теперь буду заново решать
благо есть ссылки в Решебнике, вернулся из задания 4.3. F.

nmalkam
16.01.2024 13:26

sequence.extend(queue_1)
sequence.extend(queue_2)
хотел спорить почему мол такой порядок, разобрался)))

год не правильный, если это важно, надо 2023

Вопреки заявлениям Яндекса, по состоянию на 23 декабря 2024 года для решения задачи можно воспользоваться методом sort(), что напрочь убивает всю пользу от самостоятельного решения этой задачи.

Антон
Антон
25.01.2024 12:41

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

total = []

def merge_sort(num):
    global total
    if len(num) == 0:
        return print(total)
    total.append(min(num))
    num2 = list(num)
    num2.pop(num2.index(min(num2)))
    merge_sort(num2)
    return

Степан
01.08.2024 15:16

Тоже поделюсь хитростью, т.к. были проблемы с пробеганием по спискам почему-то:

def merge(nums_1: tuple, nums_2: tuple):
merged_list = list(nums_1) + list(nums_2)
result = []

while merged_list != []:
result.append(min(merged_list))
merged_list.remove(min(merged_list))

return tuple(result)

Ольга
Ольга
04.10.2024 14:32

Здравствуйте. А если через вложенные циклы? Яндекс такой вариант принимает.
def merge(a, b):
    result = list(a + b)
    length = len(result)
    for i in range(length):
        for j in range(0, length – i – 1):
            if result[j] > result[j + 1]:
                result[j], result[j + 1] = result[j + 1], result[j]
    return tuple(result)
Можно еще с set() на случай, если в исходных кортежах есть повторяющиеся значения, но Яндексу это не нравится. Почему – неизвестно. Конкретного ответа нет.