Wagner-Fischer拼写检查中重复字母处理方法及距离计算异常排查求助
Wagner-Fischer拼写检查中重复字母处理方法及距离计算异常排查求助
嘿,我帮你揪出问题所在啦!你的Wagner-Fischer实现逻辑有个关键错误,导致重复字母场景下计算出了错误的编辑距离。
先复盘下你的问题:测试baana和cats的编辑距离时,预期是4,但代码算出3,而且你发现是三个a搞乱了结果——这完全是因为递推逻辑不符合算法的正确规则。
来看你的代码核心循环:
for i, line in enumerate(distance_matrix): for j, d in enumerate(line): if d is None: distance_matrix[i][j] = min(distance_matrix[i-1][j-1], distance_matrix[i][j-1], distance_matrix[i-1][j]) if word[i] != destination[j]: distance_matrix[i][j] += 1
这里的错误在于:当两个字符相等时,你不该取三个方向的最小值,而是直接继承左上角(i-1,j-1)的值。因为字符相等时,不需要任何编辑操作,距离就等于两个子串(去掉当前字符)的距离。而你的代码不管字符是否相等,先取三个方向的min,这会在重复字符场景下错误地“捡”到更小的插入/删除操作值,导致总距离偏小。
举个简单的例子:计算aa到a的编辑距离,正确结果是1(删除一个a),但你的代码会算出0——就是因为处理第二个a时,错误地取了左上角(i=1,j=1)的0,而不是正确的i=1,j=0的1。
修正后的正确循环逻辑应该是这样的:
# 遍历矩阵,跳过已初始化的第一行和第一列 for i in range(1, wordlen): for j in range(1, destinationlen): if word[i] == destination[j]: # 字符相等,无需操作,直接继承左上角的距离 distance_matrix[i][j] = distance_matrix[i-1][j-1] else: # 字符不等,取替换、插入、删除三种操作的最小代价+1 distance_matrix[i][j] = min( distance_matrix[i-1][j-1], # 替换当前字符 distance_matrix[i][j-1], # 在word中插入字符 distance_matrix[i-1][j] # 从word中删除字符 ) + 1
这样修改后,再测试baana和cats的距离就会得到正确的4,baana和banana的距离也依然是1,完全符合预期。
另外提个小优化:你原来用enumerate遍历整个矩阵,其实只需要从i=1和j=1开始遍历就行,因为第一行和第一列已经初始化好了,这样能避免不必要的判断。
备注:内容来源于stack exchange,提问作者Owen
相关产品推荐
相关产品推荐

