Решение задачи #33. Python Яндекс CodeRun, Расстояние по Левенштейну

Опубликовано: 23.12.2024, 00:20 | Автор: hdhAI

Вариант решения задачи на языке программирования Python с Яндекс CodeRun.
Категория: Алгоритмы.
Название задачи: Расстояние по Левенштейну.
Сложность: Средняя.
Статус решения: "Решено".

Условие задачи:
Дана текстовая строка. С ней можно выполнять следующие операции:

Заменить один символ строки на другой символ.
Удалить один произвольный символ.
Вставить произвольный символ в произвольное место строки.

Например, при помощи первой операции из строки «СОК» можно получить строку «СУК», при помощи второй операци — строку «ОК», при помощи третьей операции — строку «СТОК».

Минимальное количество таких операций, при помощи которых можно из одной строки получить другую, называется стоимостью редактирования или расстоянием Левенштейна.

Определите расстояние Левенштейна для двух данных строк.

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

Формат вывода:
Требуется вывести одно число — расстояние Левенштейна для данных строк.

Решение:


Python

import sys

def levenshtein_distance(str1, str2):
    """
    Вычисляет расстояние Левенштейна между двумя строками.

    Args:
        str1: Первая строка.
        str2: Вторая строка.

    Returns:
        Расстояние Левенштейна между строками.
    """

    n = len(str1)
    m = len(str2)

    # Создаем матрицу (n+1) x (m+1) для хранения расстояний
    # dp[i][j] - расстояние между str1[:i] и str2[:j]
    dp = [[0] * (m + 1) for _ in range(n + 1)]

    # Инициализация первого столбца и первой строки
    # dp[i][0] = i - количество удалений, чтобы получить пустую строку из str1[:i]
    # dp[0][j] = j - количество вставок, чтобы получить str2[:j] из пустой строки
    for i in range(n + 1):
        dp[i][0] = i
    for j in range(m + 1):
        dp[0][j] = j

    # Заполняем оставшуюся часть матрицы
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            cost = 0 if str1[i - 1] == str2[j - 1] else 1  # Стоимость замены
            dp[i][j] = min(
                dp[i - 1][j] + 1,      # Удаление из str1
                dp[i][j - 1] + 1,      # Вставка в str1
                dp[i - 1][j - 1] + cost # Замена/совпадение
            )
    return dp[n][m]

def main():
    """
    Основная функция программы.
    Считывает входные данные и выводит результат.
    """
    str1 = sys.stdin.readline().strip()
    str2 = sys.stdin.readline().strip()

    result = levenshtein_distance(str1, str2)
    print(result)

if __name__ == "__main__":
    main()

Объяснение кода


Алгоритм, используемый в коде, основан на динамическом программировании. Он строит матрицу dp, где dp[i][j] представляет собой расстояние Левенштейна между первыми i символами строки str1 и первыми j символами строки str2.

Инициализация:
Первая строка и первый столбец матрицы инициализируются значениями от 0 до n и от 0 до m соответственно. Это соответствует случаям, когда одна из строк пустая.

Заполнение матрицы:
Для каждой ячейки dp[i][j] вычисляется минимальное значение из трех вариантов:
dp[i-1][j] + 1: Удаление символа из str1.
dp[i][j-1] + 1: Вставка символа в str1.
dp[i-1][j-1] + cost: Замена символа в str1 (если символы не совпадают, cost = 1, иначе cost = 0).

Результат:
Значение dp[n][m] содержит искомое расстояние Левенштейна.

Данный код достаточно оптимизирован для решения задачи с ограничениями по длине строк в 1000 символов. Использование динамического программирования позволяет избежать рекурсивных вызовов и экспоненциального роста времени выполнения. Временная сложность алгоритма O(n*m), где n и m - длины строк. Использование матрицы dp для хранения промежуточных результатов предотвращает повторные вычисления. Код эффективно решает задачу и проходит тесты с заданными ограничениями по времени и памяти.

Источник решения: hdhai.com

Похожие статьи
Интересное





Warning: file_put_contents(/var/www/angella1/data/www/hdhai.com/counter/count.php): Failed to open stream: Permission denied in /var/www/angella1/data/www/hdhai.com/counter.php on line 89