近似字符串匹配的具体算法代码

时间:2012-05-28 22:43:19

标签: string algorithm data-structures string-matching

Approximate string matching并不是一个陌生人的问题。

我正在学习并试图了解如何解决它。我现在甚至不想深入了解它,只是想了解蛮力的方式。

在其维基页面(Approximate string matching)中,它说

  

蛮力方法是计算T的所有子串的P(模式)的编辑距离,然后选择具有最小距离的子串。但是,该算法的运行时间为O(m * n ^ 3),n为T的长度,m为P的长度

确定。我通过以下方式理解这个陈述:

  1. 我们找出T
  2. 的所有可能的子串
  3. 我们计算每对字符串的编辑距离{P,t1},{P,t2},...
  4. 我们找出哪个子串与P的距离最短,这个子串就是答案。
  5. 我有以下问题:

    一个。我可以使用两个for循环来获取所有可能的子串,这需要O(n ^ 2)。所以当我尝试计算一个子串和模式的编辑距离时,它是否需要O(n * m)?为什么呢?

    湾我究竟如何计算一对(一个子串和模式)的距离?我知道我可以插入,删除,替换,但任何人都可以给我一个只计算一对的算法吗?

    由于


    修改

    好的,我应该使用Levenshtein distance,但我不太了解它的方法。

    以下是代码的一部分

    for j from 1 to n
    {
        for i from 1 to m
        {
          if s[i] = t[j] then  
            d[i, j] := d[i-1, j-1]       // no operation required
          else
            d[i, j] := minimum
                       (
                         d[i-1, j] + 1,  // a deletion
                         d[i, j-1] + 1,  // an insertion
                         d[i-1, j-1] + 1 // a substitution
                       )
        }
      }
    

    所以,假设我现在正在比较{"suv", "svi"}

    所以'v' != 'i',那么我必须看到另外三对:

    1. {"su", "sv"}
    2. {"suv", "sv"}
    3. {"su", "svi"}
    4. 我如何理解这部分内容?为什么我需要看到这三个部分?

      distance between two prefixes是否意味着我们需要distance次更改以使两个前缀(或字符串)相等?

      那么,让我们来看看{"su", "sv"}。我们可以看到{"su", "sv"}的距离为1.那么{"su", "sv"}如何通过添加1来成为{"suv", "svi"}?我认为我们需要将'v'插入“su”并将'v'插入“sv”,然后用'v'替换最后的'i',其中涉及3个操作,对吗?

1 个答案:

答案 0 :(得分:1)

测量两个字符串之间编辑距离的标准方法称为Levenshtein distance - 维基百科页面包含算法的伪代码。

至于您的修改:您需要查看{"su", "sv"},因为将"suv"更改为"svi"的最佳方法是将v替换为i "su",其费用将高于将"sv"更改为"suv"的费用。或者,可能最好的方法是以某种方式将"sv"更改为i,然后添加v。或者,最好的方法是首先从"suv"删除"su",然后将"svi"更改为u。在这种情况下,第一种方式最好(或与其他选项一样好)。编辑距离确实为2,操作是将v更改为v,将i更改为{{1}}。