Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 高效地计算两个字符串之间的编辑距离_Algorithm_Edit Distance - Fatal编程技术网

Algorithm 高效地计算两个字符串之间的编辑距离

Algorithm 高效地计算两个字符串之间的编辑距离,algorithm,edit-distance,Algorithm,Edit Distance,我有一个长度为1000的字符串S和一个长度为100的查询字符串Q。我想用长度为100的字符串S的每个子字符串计算查询字符串Q的编辑距离。一种简单的方法是独立地动态计算每个子字符串的编辑距离,即edDist(q,s[0:100]),edDist(q,s[1:101]),edDist(q,s[2:102])edDist(q,s[900:1000]) def edDist(x, y): """ Calculate edit distance between sequences x and y usin

我有一个长度为1000的字符串S和一个长度为100的查询字符串Q。我想用长度为100的字符串S的每个子字符串计算查询字符串Q的编辑距离。一种简单的方法是独立地动态计算每个子字符串的编辑距离,即
edDist(q,s[0:100])
edDist(q,s[1:101])
edDist(q,s[2:102])
<代码>edDist(q,s[900:1000])

def edDist(x, y):
""" Calculate edit distance between sequences x and y using
    matrix dynamic programming.  Return distance. """
D = zeros((len(x)+1, len(y)+1), dtype=int)
D[0, 1:] = range(1, len(y)+1)
D[1:, 0] = range(1, len(x)+1)
for i in range(1, len(x)+1):
    for j in range(1, len(y)+1):
        delt = 1 if x[i-1] != y[j-1] else 0
        D[i, j] = min(D[i-1, j-1]+delt, D[i-1, j]+1, D[i, j-1]+1)
return D[len(x), len(y)]
有人能提出一种替代方法来有效地计算编辑距离吗。我对这一点的看法是,我们知道edDist(q,s[900:1000])。我们是否可以利用这些知识来计算
edDist[(q,s[899:999])]
…因为在那里我们只有一个字符的差异,然后使用之前计算的编辑距离返回到
edDist[(q,s[1:100])]

提高空间复杂度 使Levenshtein距离算法更有效的一种方法是减少计算所需的内存量

要使用整个矩阵,需要使用
O(n*m)
内存,其中
n
表示第一个字符串的长度,
m
表示第二个字符串的长度

如果你仔细想想,我们真正关心的是矩阵的最后两列——前一列和当前列

知道这一点,我们可以假装我们有一个矩阵,但只有真正创建这两列;当我们需要更新数据时,写入数据

这里我们只需要两个大小为
n+1
的数组:

var column_crawler_0 = new Array(n + 1);
var column_crawler_1 = new Array(n + 1);
初始化这些伪列的值:

for (let i = 0; i < n + 1; ++i) {
  column_crawler_0[i] = i;
  column_crawler_1[i] = 0;
}
for(设i=0;i
然后检查您的常规算法,但只需确保在执行过程中使用新值更新这些数组:

for (let j = 1; j < m + 1; ++j) {
  column_crawler_1[0] = j;
  for (let i = 1; i < n + 1; ++i) {
    // Perform normal Levenshtein calculation method, updating current column
    let cost = a[i-1] === b[j-1] ? 0 : 1;
    column_crawler_1[i] = MIN(column_crawler_1[i - 1] + 1, column_crawler_0[i] + 1, column_crawler_0[i - 1] + cost);
  }

  // Copy current column into previous before we move on
  column_crawler_1.map((e, i) => {
    column_crawler_0[i] = e;
  });
}

return column_crawler_1.pop()
for(设j=1;j{
列_爬虫_0[i]=e;
});
}
返回列\u crawler\u 1.pop()
如果你想进一步分析这种方法,我写了一篇文章,所以如果你好奇的话,请随意查看

提高时间复杂度
没有任何简单的方法可以改进Levenshtein距离算法,使其执行速度比
O(n^2)
更快。有几种复杂的方法,一种是使用。如果你对它们感兴趣的话,有一些很好的来源,而且这些方法可以达到
O(nlgn)

的渐近速度,大致上
O(n^2)
与Levenshtein距离一样好。有一些方法比动态规划矩阵方法更能提高内存效率,但速度并不是很快increase@NickZuber提高内存效率的方法有哪些?留下了一个更深入的答案