R 中有一个名为的包stringdist
,其中包含用于计算 Levenshtein 字符串距离的函数。这个包有两个问题:
第一个它不适用于大字符串,例如:
set.seed(1)
a.str <- paste(sample(0:9, 100000, replace = T), collapse="")
set.seed(2)
b.str <- paste(sample(0:9, 100000, replace = T), collapse="")
stringdist(a.str, b.str, method = "lv")
# THE LAST COMMAND RESTARTS R SESSION
向量中的第二距离是按向量元素的字符而不是按整个向量计算的:
a.vec <- c(1, 2, 3, 4, 5, 666)
b.vec <- c(1, 2, 4, 3, 6, 777)
stringdist(a.vec, b.vec, method = "lv")
# [1] 0 0 1 1 1 3
我想得到最后一个命令 4 的结果:因为需要 4 次替换(对应位置上的 4 个向量元素不同)。在这种情况下,我可以获取非 0 的值并计算它们,例如:r <- stringdist(a.vec, b.vec, method = "lv"); length(r[r!=0])
. 但它在以下示例中不起作用:
a.vec <- c(1, 2, 3)
b.vec <- c(1, 2, 2, 3)
stringdist(a.vec, b.vec, method = "lv")
# [1] 0 0 1 1
# Warning message:
# In stringdist(a.vec, b.vec, method = "lv") :
# longer object length is not a multiple of shorter object length
我想得到最后一个命令 1 的结果(在第一个向量的第一个位置插入 2)。
PS还有内置的实现,但它也不适用于大字符串(老实说,我不知道它是如何处理向量的,因为我不明白它的输出):
adist(a.str,b.str, counts = T)
# Error in adist(a.str, b.str, counts = T) :
# 'Calloc' could not allocate memory (1410265409 of 8 bytes)
是否有任何实现(最好在 python、perl 或 R 中)满足我的要求?非常感谢。
PPS我有多个文件,其中每行包含 1 ~ 500 的数字(这就是为什么我需要将例如 347 视为一个元素而不是由 3、4、7 组成的字符串,因为 3、4、7 是另一个单独的数字)。这些文件有 ~ 250000 行。我想知道这些文件彼此之间有多相似。我想 10k*10k 大小是问题所在。但这里提到的 Levenshtein 算法只使用 2*10k 大小(如果两个字符串都是 10k 长)。我想诀窍是它只计算结果而忘记了结果是如何计算的,但这对我来说没问题。汉明距离对我来说还不够,因为我需要考虑插入、删除、替换,在汉明中这两个字符串1234567890
0123456789
是完全不同的,但在 Levenshtein 中它们是相似的。