Нашли ошибку?

Восстановить общую подпоследовательность

СложнаяНайти ошибку2 ошибкиГлава 9

#динамическое программирование#общая подпоследовательность#восстановление ответаid: ga-lcs-restore

Функция lcs(a, b) возвращает саму самую длинную общую подпоследовательность, а не только её длину. Сначала она заполняет таблицу, как в главе, затем проходит по ней от правого нижнего угла и собирает символы. Таблица заполняется верно, но при восстановлении есть две ошибки. Найдите и исправьте их.

Примеры

lcs("рыбак", "бирка")   # "рк" — или другая общая подпоследовательность длины 2
lcs("abcbdab", "bdcaba")   # одна из подпоследовательностей длины 4, например "bcba"

Правила

Решение

def lcs(a: str, b: str) -> str:
    """Одна из самых длинных общих подпоследовательностей a и b."""
    n, m = len(a), len(b)
    table = [[0] * (m + 1) for _ in range(n + 1)]
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            if a[i - 1] == b[j - 1]:
                table[i][j] = table[i - 1][j - 1] + 1
            else:
                table[i][j] = max(table[i - 1][j], table[i][j - 1])

    result = []
    i, j = n, m
    while i > 0 and j > 0:
        if a[i - 1] == b[j - 1]:
            result.append(a[i - 1])
            i -= 1
            j -= 1
        elif table[i - 1][j] <= table[i][j - 1]:
            i -= 1
        else:
            j -= 1
    return "".join(result)

Можно решать и в своём редакторе: «Скопировать с тестами» и запустите python3 lcs_restore.py — тесты те же, результат покажет ✓ / ✗ и итог.