我已经实现了算法,但现在我想找到与其他字符串编辑距离最短的字符串的编辑距离。
以下是算法:
def lev(s1, s2):
return min(lev(a[1:], b[1:])+(a[0] != b[0]), lev(a[1:], b)+1, lev(a, b[1:])+1)
答案 0 :(得分:5)
您的“实施”有几个缺陷:
(1)它应该以{{1}}开头,而不是def lev(a, b):
。请先了解(a)运行代码之前的好习惯(b)引用您实际运行的代码(通过复制/粘贴,而不是(容易出错)重新键入)。
(2)没有终止条件;对于任何参数,它最终会最终尝试评估def lev(s1, s2):
,如果不是Python实现限制,它将永远循环:lev("", "")
。
您需要插入两行:
RuntimeError: maximum recursion depth exceeded
让它发挥作用。
(3)Levenshtein距离是递归定义的 。没有“这个”(唯一的)算法。递归代码在教室外很少见,然后只能以“稻草人”的身份出现。
(4)天真的实现需要时间和内存与if not a: return len(b)
if not b: return len(a)
成比例...那些字符串通常不会比4到8长一点吗?
(5)你的天真实施更糟糕,因为它复制了输入片段。
你可以在网上找到工作非常天真的实现... google(“levenshtein python”)...寻找那些使用len(a) * len(b)
额外内存的实现。< / p>
你要求的是什么(“与其他字符串编辑距离最短的字符串的编辑距离。”)没有意义......“字符串”??? “探戈需要两个人”: - )
您可能想要的(找到具有最小距离的集合中的所有字符串对),或者可能只是最小距离,这是一个简单的编程练习。你有什么尝试?
顺便说一句,通过简单算法找到这些对将需要执行O(max(len(a), len(b)))
的O(N ** 2),其中N是集合中的字符串数...如果这是真实世界应用程序,您应该使用经过验证的代码而不是尝试自己编写代码。如果这是作业,你应该这样说。
答案 1 :(得分:0)
这就是你要找的东西吗?
import itertools
import collections
# My Simple implementation of Levenshtein distance
def levenshtein_distance(string1, string2):
"""
>>> levenshtein_distance('AATZ', 'AAAZ')
1
>>> levenshtein_distance('AATZZZ', 'AAAZ')
3
"""
distance = 0
if len(string1) < len(string2):
string1, string2 = string2, string1
for i, v in itertools.izip_longest(string1, string2, fillvalue='-'):
if i != v:
distance += 1
return distance
# Find the string with the shortest edit distance.
list_of_string = ['AATC', 'TAGCGATC', 'ATCGAT']
strings_distances = collections.defaultdict(int)
for strings in itertools.combinations(list_of_string, 2):
strings_distances[strings[0]] += levenshtein_distance(*strings)
strings_distances[strings[1]] += levenshtein_distance(*strings)
shortest = min(strings_distances.iteritems(), key=lambda x: x[1])