编辑距离

NLP中有个 编辑距离 的概念,常运用到单词纠错中。本博文介绍并代码实现 编辑距离。参考并综合以下三篇博文。


 

代码思路 

# 1)首先考虑A串的第一个字符
#
#   假设存在两个字符串A和B,他们的长度分别是lenA和lenB。首先考虑第一个字符,由于他们是一样的,所以只需要计算A[2...lenA]和B[2...lenB]之间的距离即可。
# 那么如果两个字符串的第一个字符不一样怎么办?可以考虑把第一个字符变成一样的(这里假设从A串变成B串):
#
# 修改A串的第一个字符成B串的第一个字符,之后仅需要计算A[2...lenA]和B[2...lenB]的距离即可;
# 删除A串的第一个字符,之后仅需要计算A[2...lenA]和B[1...lenB]的距离即可;
# 把B串的第一个字符插入到A串的第一个字符之前,之后仅需要计算A[1...lenA]和B[2...lenB]的距离即可。

# 2)接下来考虑A串的第i个字符和B串的第j个字符。
#
#   我们这个时候不考虑A的前i-1字符和B串的第j-1个字符。如果A串的第i个字符和B串的第j个字符相等,即A[i]=B[j],则只需要计算A[i...lenA]和B[j...lenB]之间的距离即可。如果不想等,则:
#
# 修改A串的第i个字符成B串的第j个字符,之后仅需要计算A[i+1...lenA]和B[j+1...lenB]的距离即可;
# 删除A串的第i个字符,之后仅需要计算A[i+1...lenA]和B[j...lenB]的距离即可;
# 把B串的第j个字符插入到A串的第i个字符之前,之后仅需要计算A[i...lenA]和B[j+1...lenB]的距离即可。

#   写到这里,自然会想到用递归求解或者动态规划求解,由于用递归会产生很多重复解,所以用动态规划。

 递归代码:

oldarr=list('kittenkitten')
newarr=list('sittingsitting')
def fun(arrA,arrB,i,j):
    if i ==len(arrA) or j==len(arrB):
        return len(arrA)+len(arrB)-i-j
    else:
        if arrA[i]==arrB[j]:
            return fun(arrA,arrB,i+1,j+1)
        else:
            return min(fun(arrA,arrB,i+1,j)+1,fun(arrA,arrB,i,j+1)+1,fun(arrA,arrB,i+1,j+1)+1)  #删除 插入 替换

print fun(oldarr,newarr,0,0)

动态规划代码:

#动态规划
# 关键在于建立二维矩阵,这时,要分清i和j分别代表什么含义。矩阵中的数字,代表什么含义。
# 总结:i和j代表两个可以相对遍历的序列长度,矩阵中的数字代表目标函数的值。
#比如:i=1 和j=2时候,表示old序列只考虑到长度是1,而目标序列,假设只考虑到长度是2
oldarr=list('kittenkitten')
newarr=list('sittingsitting')

def funDynamic(oldarr,newarr):
    arrValue = []
    lenI = len(oldarr) + 1
    lenJ = len(newarr) + 1
    for i in range(lenI):
        arrValue.append([0] * lenJ)
    for i in range(lenI):
        for j in range(lenJ):
            if i==0 or j==0:
                arrValue[i][j] = i+j
                continue
            if oldarr[i-1]==newarr[j-1]:
                d = 0
            else:
                d = 1
                
            # 分别对应:插入、删除、替换 操作
            arrValue[i][j] =min(arrValue[i - 1][j] + 1, arrValue[i][j-1] + 1, arrValue[i-1][j-1] + d)
    for i in range(lenI):
        print arrValue[i]
    print arrValue[lenI-1][lenJ-1]

funDynamic(oldarr,newarr)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值