什么是以与版本页面上的SO相同的方式对两个字符串进行区分的算法?

时间:2009-09-03 04:45:21

标签: c# ruby algorithm

我试图逐个区分两个字符串,类似于StackOverflow在版本编辑页面上对两个字符串进行区分的方式。这样做的算法是什么?是否有宝石或其他标准库来实现这一目标?

编辑:我见过其他差异算法(Differ与Ruby),它们似乎导致以下结果:

>> o = 'now is the time when all good men.'
>> p = 'now some time the men time when all good men.'
>> Differ.diff_by_word(o,p).format_as(:html)
=> "now <del class=\"differ\">some</del><ins class=\"differ\">is</ins> 
   <del class=\"differ\">time </del>the <del class=\"differ\">men </del>time
   when all good men."

请注意单词基于每个单词的差异?我想通过短语进行更多区分,所以上面的代码输出:

=> "now <del class=\"differ\">some time the men</del><ins class=\"differ\">is
   the</ins> time when all good men."

我希望得到太多吗?

1 个答案:

答案 0 :(得分:4)

您正在寻找的算法是Longest Common Subsequence,它可以为您完成大部分工作。

大纲就是这样。

  1. 按字词分组(输入,输出)
  2. 计算输入/输出阵列上的LCS。
  3. 遍历阵列并智能地连接区域。
  4. 例如,你说:

    “你好世界这是一个考验”

    与之相比:

    “先生你好世界”

    LCS的结果是

    • “先生”+
    • “你好”=
    • “world”=
    • “this” -
    • “是” -
    • “a” -
    • “test” -

    现在你在建立时撒上特制的酱汁。你加入了这个字符串,同时保持对前一个动作的注意。朴素算法只是连接相同动作的部分。

    • “先生”+
    • “你好世界”=
    • “这是一个测试” -

    最后你将它转换为html:

    <ins>mister</ins> hello world <del>this is a test</del>  
    

    当然,魔鬼的细节如下:

    • 您需要考虑如何处理标记
    • 你比较markdown还是html
    • 是否存在UI停止有意义的边缘情况。
    • 您是否需要特殊处理标点符号。