Ruby 如何修改Damerau-Levenshtein算法,使其也包括较大子字符串的开始索引和结束索引?

Ruby 如何修改Damerau-Levenshtein算法,使其也包括较大子字符串的开始索引和结束索引?,ruby,algorithm,levenshtein-distance,Ruby,Algorithm,Levenshtein Distance,这是我的密码: #http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance # used for fuzzy matching of two strings # for indexing, seq2 must be the parent string def dameraulevenshtein(seq1, seq2) oneago = nil min = 100000000000 #index

这是我的密码:

#http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
# used for fuzzy matching of two strings
# for indexing, seq2 must be the parent string
  def dameraulevenshtein(seq1, seq2)
      oneago = nil
      min = 100000000000 #index
      max = 0 #index
      thisrow = (1..seq2.size).to_a + [0]
      seq1.size.times do |x|
          twoago, oneago, thisrow = oneago, thisrow, [0] * seq2.size + [x + 1]
          seq2.size.times do |y|
              delcost = oneago[y] + 1
              addcost = thisrow[y - 1] + 1
              subcost = oneago[y - 1] + ((seq1[x] != seq2[y]) ? 1 : 0)
              thisrow[y] = [delcost, addcost, subcost].min
              if (x > 0 and y > 0 and seq1[x] == seq2[y-1] and seq1[x-1] == seq2[y] and seq1[x] != seq2[y])
                  thisrow[y] = [thisrow[y], twoago[y-2] + 1].min
              end
          end
      end
      return thisrow[seq2.size - 1], min, max
  end
必须有某种方法来获取子字符串seq1的起始索引和结束索引,以及父字符串seq2,对吗

我不完全确定这个算法是如何工作的,即使在阅读了关于它的wiki文章之后。我的意思是,我理解最高层次的解释,因为它发现了插入、删除和转置差异(第二个循环中的行)。。但除此之外。我有点迷路了

下面是一个我想用这个(^)来做的事情的例子:

索引应为:

  start: 5
  end:   18 (last char of string)
理想情况下,永远不会修改搜索字符串。但是,我想我可以去掉所有的空白字符(因为只有..3?\n\r和\t)存储每个空白字符的索引,获取子字符串的索引,然后重新添加空白字符,确保补偿子字符串的索引,因为我用最初在子字符串中的空白字符偏移它们。-但是如果这一切都可以用同样的方法来完成,那将是令人惊讶的,因为算法已经是O(n^2)=(


在某些情况下,我只允许空白字符分割子字符串(s1)…但每次只做一件事

我认为此算法不是您想要做的正确选择。该算法只是根据将一个字符串转换为另一个字符串所需的修改次数来计算两个字符串之间的距离。如果为了简洁起见,我们将函数重命名为dlmatch,并且只返回距离,则t我们有:

dlmatch("hello there", "uh, \n\thello\n\t there"
=> 7
这意味着您可以在7个步骤中将一个字符串转换为另一个字符串(有效地从第二个字符串中删除7个字符)。问题是,7个步骤的差别很大:

dlmatch("hello there", "panda here"
=> 6
这实际上意味着“hello there”和“panda here”比第一个示例更接近匹配

如果您试图做的是“找到一个主要匹配的子字符串”,我认为您在将第一个字符串馈送给第二个字符串的一系列子字符串,然后选择提供最接近匹配的子字符串时,会遇到O(n^3)算法


或者,您最好先对搜索字符串进行预处理,然后再对子字符串进行regexp匹配。例如,您可以去掉所有特殊字符,然后构建一个regexp,在子字符串中查找不区分大小写的单词,这些单词之间可以有任意数量的空格。

I don’我不认为该算法是您想要做的事情的正确选择。该算法只是根据将一个字符串转换为另一个字符串所需的修改次数来计算两个字符串之间的距离。如果为了简洁起见,我们将函数重命名为dlmatch,并且只返回距离,那么我们有:

dlmatch("hello there", "uh, \n\thello\n\t there"
=> 7
这意味着您可以在7个步骤中将一个字符串转换为另一个字符串(有效地从第二个字符串中删除7个字符)。问题是,7个步骤的差别很大:

dlmatch("hello there", "panda here"
=> 6
这实际上意味着“hello there”和“panda here”比第一个示例更接近匹配

如果您试图做的是“找到一个主要匹配的子字符串”,我认为您在将第一个字符串馈送给第二个字符串的一系列子字符串,然后选择提供最接近匹配的子字符串时,会遇到O(n^3)算法


或者,您最好尝试对搜索字符串进行预处理,然后与子字符串进行regexp匹配。例如,您可以去掉所有特殊字符,然后构建一个regexp,在子字符串中查找不区分大小写的单词,这些单词之间可以有任意数量的空格。

如果使用模糊匹配,我不确定您将如何定义第一个字符串的起始索引和结束索引。您能给出一对字符串的示例以及您要查找的内容吗?刚刚添加到我的问题中。谢谢!=d由于使用模糊匹配,我不确定您将如何定义第一个字符串的起始索引和结束索引。您能我举了一对字符串的例子,你在找什么?刚刚添加到我的问题中。谢谢!=d根据你说的:
“呃,\n\thello\n\t在那里”。匹配(/(hello)\s*(那里)/)do | m | pm.begin(1)#=>5pm.end(2)#=>18 end
如果你计算距离,然后看看这==两个字符串之间的长度差,你可以假设一个字符串在另一个字符串中,这是真的,但是你最好只进行子字符串搜索,这比使用差分函数快得多(O(n))匹配(/(hello)\s*(there)/)do | m | pm.begin(1)#=>5pm.end(2)#=>18end如果你计算距离,然后看看这==两个字符串之间的长度差,你可以假设一个字符串在另一个字符串中,这是真的,但你也可以只进行子字符串搜索,搜索速度会快得多(O(n))而不是使用差分函数。