更有效的方式查找编辑距离在一个大的数组

More efficient way of finding edit distance over a large array

本文关键字:一个 数组 方式 有效 查找 编辑距离      更新时间:2023-10-16

我有一个很大的单词数组(300,000个单词),我想找到每个单词之间的编辑距离,所以我只是对它进行迭代,并运行这个版本的levenstein算法:

unsigned int edit_distance(const std::string& s1, const std::string& s2)
{
    const std::size_t len1 = s1.size(), len2 = s2.size();
    std::vector<std::vector<unsigned int>> d(len1 + 1, std::vector<unsigned int>(len2 + 1));
d[0][0] = 0;
for (unsigned int i = 1; i <= len1; ++i) d[i][0] = i;
for (unsigned int i = 1; i <= len2; ++i) d[0][i] = i;
for (unsigned int i = 1; i <= len1; ++i)
    for (unsigned int j = 1; j <= len2; ++j)
        // note that std::min({arg1, arg2, arg3}) works only in C++11,
        // for C++98 use std::min(std::min(arg1, arg2), arg3)
        d[i][j] = std::min({ d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1) });
return d[len1][len2];
}

所以我想知道的是,是否有更有效的方法来做到这一点,我听说过Levenshtein Autonoma,但我不确定它是否更有效。

我可以想象,在那里你可以避免处理相同的事情一遍又一遍通过预处理的东西,但我不知道如何实际实现它(一些近似的计算将是预处理一切将是大约10^28操作,所以这不会是一个改进)

正如他在评论中所说,OP实际上是在寻找编辑距离小于2的所有对。

给定n个单词的输入,一种朴素的方法是进行n(n-1)/2次比较,但当L在编辑距离(字符串的度量空间)中时,可能需要较少的比较。

Levenshtein距离是一个度量空间,并且满足4个必需的度量公理——包括三角形不等式。

编辑:

考虑到这一点,我们可以使用Sergey Brin (Google的联合创始人)在1995年的论文中大度量空间中的近邻搜索中提出的方法来解决我们的问题。

引自本文:给定一个度量空间(X, d),一个数据集Y⊥X,一个查询点X∈X,一个值域r∈r, X的近邻是点Y∈Y的集合,使得d(X, Y)≤r。

在本文中,Brin引入了GNAT(几何近邻访问树)——一种解决这一问题的数据结构。Brin使用Levenshtein距离(他称之为"编辑距离")对两个文本语料库测试了他的算法的性能。

多年来,GNAT已被广泛使用。对几何近邻访问树(GNAT)提出的GNAT的一些改进进行了重新审视- Fredriksson 2016。

如果如注释所示,您实际想要的是找到编辑距离最多为2的对,则可以从每个单词生成最多删除两个字符(最多500个左右)的所有可能性,并将这些字符存储在散列表中。然后,您只需要检查散列桶中的每一对单词,通过查看删除是否重合,这可能并不难。

相关文章: