Levenshtein Distance 編輯距離

參考資料:
算法實現:Levenshtein Distance, in Three Flavors
原理:wiki-Levenshtein distance

該距離是俄羅斯科學家Vladimir Levenshtein在1965年發明的,也叫做編輯距離(實際上編輯距離代表一大類算法),距離代表著從s到t需要刪、插、代替單個字符的最小步驟數。
主要應用:

  • Spell checking 檢查拼寫
  • Speech recognition 語音識別
  • DNA analysis DNA分析
  • Plagiarism detection 檢測抄襲

主要原理(理解下面的公式):
ai跟bj之間的變化差距可以有很多種方法,這里限定最后一個字符ai和bj最后一個變化。可以刪除其中一個,然后交給下一次去變化,這里包含了min里面的前兩個;可以變換最后一個相等,交給下一次去變化,最后一個相等的情況下,這里也可以不變。


自己實現的:

import my_common


@my_common.print_result_after
def levenshtein_distance(str1,str2):
    matrix_width = len(str1) + 1
    matrix_height = len(str2) + 1
    matrix = [[0] * matrix_width for i in range(matrix_height)]

    # 初始化
    for i in range(matrix_width):
        matrix[0][i] = i

    for j in range(matrix_height):
        matrix[j][0] = j

    for i in range(1, matrix_height):
        for j in range(1, matrix_width, ):
            if str1[j - 1] == str2[i - 1]:
                cost = 0
            else:
                cost = 1
            try:
                a = matrix[i - 1][j] + 1
                b = matrix[i][j - 1] + 1
                c = matrix[i - 1][j - 1] + cost

                matrix[i][j] = min(a, b, c)
            except Exception as e:
                print(e)
                print('{}-{}'.format(i, j))
    print(matrix)
    return matrix[-1][-1]


# 遞歸版本
@my_common.print_result_after
def levenshtein_distance2(str1,str2):
    width = len(str1) + 1
    height = len(str2) + 1
    mat = [[-1]*width for _ in range(height)]

    def levenshtein_distance2_1(i, j):
        # 這個是為了遞歸的時候避免重復計算
        if mat[i][j] != -1:
            return mat[i][j]

        if i == 0:
            mat[i][j] = j
        elif j == 0:
            mat[i][j] = i
        else:
            if str2[i-1] == str1[j-1]:
                cost = 0
            else:
                cost = 1

            mat[i][j] = min(levenshtein_distance2_1(i-1,j)+1, levenshtein_distance2_1(i,j-1) + 1,
                            levenshtein_distance2_1(i - 1, j - 1) + cost)

        return mat[i][j]

    levenshtein_distance2_1(height-1,width-1)
    print(mat)
    return mat[-1][-1]


def main():
    str1 = 'hello'
    str2 = 'ello'
    # [[0, 1, 2, 3, 4, 5], [1, 1, 1, 2, 3, 4], [2, 2, 2, 1, 2, 3], [3, 3, 3, 2, 1, 2], [4, 4, 4, 3, 2, 1]]
    # 1
    levenshtein_distance2(str1,str2)


if __name__ == '__main__':
    main()

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。