我有两个很长的列表,我想在第二个列表中为第一个列表的每个元素找到最长的公共(public)子字符串。
一个简化的例子是
L1= ["a_b_c","d_e_f"]
L2=["xx""xy_a","xy_b_c","z_d_e","zl_d","z_d_e_y"]
所以我想在 L2 ("xy_b_c") 中找到 "a_b_c"的最佳匹配,然后在 L2("z_d_e_y") 中找到 "d_e_f"的最佳匹配。最适合我的是具有最长公共(public)字符的字符串。在 我查看了 Levenshtein Distance 的示例,它适用于小列表( http://www.stavros.io/posts/finding-the-levenshtein-distance-in-python/ ),但我的列表 L2 有 163531 个元素,并且在过去的 15 分钟内甚至找不到一个匹配项..
我没有 CS 背景,有人能告诉我一些更好的算法(或者更好的算法实现吗?:))非常感谢。
当前代码(从 stackoverflow 复制链接和其他人):
L1= ["a_b_c","d_e_f"]
L2=["xx""xy_a","xy_b_c","z_d_e","zl_d","z_d_e_y"]
def levenshtein_distance(first, second):
"""Find the Levenshtein distance between two strings."""
if len(first) > len(second):
first, second = second, first
if len(second) == 0:
return len(first)
first_length = len(first) + 1
second_length = len(second) + 1
distance_matrix = [[0] * second_length for x in range(first_length)]
for i in range(first_length):
distance_matrix[i][0] = i
for j in range(second_length):
distance_matrix[0][j]=j
for i in xrange(1, first_length):
for j in range(1, second_length):
deletion = distance_matrix[i-1][j] + 1
insertion = distance_matrix[i][j-1] + 1
substitution = distance_matrix[i-1][j-1]
if first[i-1] != second[j-1]:
substitution += 1
distance_matrix[i][j] = min(insertion, deletion, substitution)
return distance_matrix[first_length-1][second_length-1]
for string in L1:
print sorted(L2,key = lambda x:levenshtein_distance(x,string))[0]
编辑 - 只需按下 control+C,它在 15 分钟后给了我一个不正确(但接近)的答案。那只是第一个字符串,还有很多..
最佳答案
使用 difflib
模块:
>>> from functools import partial
>>> from difflib import SequenceMatcher
def func(x, y):
s = SequenceMatcher(None, x, y)
return s.find_longest_match(0, len(x), 0, len(y)).size
...
for item in L1:
f = partial(func, item)
print max(L2, key=f)
...
xy_b_c
z_d_e_y
关于python - 两个长列表之间的最长公共(public)子串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20420686/