|
| 1 | +""" |
| 2 | +Author : Alexander Pantyukhin |
| 3 | +Date : October 14, 2022 |
| 4 | +This is implementation Dynamic Programming up bottom approach |
| 5 | +to find edit distance. |
| 6 | +The aim is to demonstate up bottom approach for solving the task. |
| 7 | +The implementation was tested on the |
| 8 | +leetcode: https://leetcode.com/problems/edit-distance/ |
| 9 | +""" |
| 10 | + |
| 11 | +""" |
| 12 | +Levinstein distance |
| 13 | +Dynamic Programming: up -> down. |
| 14 | +""" |
| 15 | + |
| 16 | + |
| 17 | +def min_distance_up_bottom(word1: str, word2: str) -> int: |
| 18 | + """ |
| 19 | + >>> min_distance_up_bottom("intention", "execution") |
| 20 | + 5 |
| 21 | + >>> min_distance_up_bottom("intention", "") |
| 22 | + 9 |
| 23 | + >>> min_distance_up_bottom("", "") |
| 24 | + 0 |
| 25 | + >>> min_distance_up_bottom("zooicoarchaeologist", "zoologist") |
| 26 | + 10 |
| 27 | + """ |
| 28 | + |
| 29 | + from functools import lru_cache |
| 30 | + |
| 31 | + len_word1 = len(word1) |
| 32 | + len_word2 = len(word2) |
| 33 | + |
| 34 | + @lru_cache(maxsize=None) |
| 35 | + def min_distance(index1: int, index2: int) -> int: |
| 36 | + # if first word index is overflow - delete all from the second word |
| 37 | + if index1 >= len_word1: |
| 38 | + return len_word2 - index2 |
| 39 | + # if second word index is overflow - delete all from the first word |
| 40 | + if index2 >= len_word2: |
| 41 | + return len_word1 - index1 |
| 42 | + diff = int(word1[index1] != word2[index2]) # current letters not identical |
| 43 | + return min( |
| 44 | + 1 + min_distance(index1 + 1, index2), |
| 45 | + 1 + min_distance(index1, index2 + 1), |
| 46 | + diff + min_distance(index1 + 1, index2 + 1), |
| 47 | + ) |
| 48 | + |
| 49 | + return min_distance(0, 0) |
| 50 | + |
| 51 | + |
| 52 | +if __name__ == "__main__": |
| 53 | + import doctest |
| 54 | + |
| 55 | + doctest.testmod() |
0 commit comments