Diff两个标识符序列

时间:2012-02-07 14:22:51

标签: algorithm language-agnostic

给定两个标识符序列,如何找到将第一个标识符序列转换为第二个标识符序列的最小操作序列。

操作可以是:

  • 在指定位置插入标识符
  • 从指定位置移除标识符
  • 将标识符从某个位置移动到另一个位置

注意:标识符是唯一的,不能在序列中出现两次

示例:

Sequence1 [1, 2, 3, 4, 5]
Sequence2 [5, 1, 2, 9, 3, 7]

Result (index are 0 based) :
- Remove at 3
- Move from 3 to 0
- Insert '9' at 3
- Insert '7' at 5

谢谢!

2 个答案:

答案 0 :(得分:1)

此指标称为Levenshtein distance或更准确地称为Damerau–Levenshtein distance

几乎所有可能的编程语言都有实现,您可以使用它来解决您描述的问题。

答案 1 :(得分:1)

首先找到longest common subsequence。这将识别不会移动的元素:

[(1), (2), (3), 4, 5]

LCS的元素括在括号中。

浏览索引0中的两个序列,记录使序列相同所需的操作。如果第一个序列的当前项不是LCS的一部分,请将其删除,并标记之前的位置,以防您以后需要插入它。如果当前元素是LCS的一部分,则从其前面的第二个序列插入元素。这可以是简单的插入,也可以是移动。如果您要插入的项目位于原始列表中,请将其移动;否则,将其作为插入。

以下是使用您的示例的演示。大括号显示当前元素

[{(1)}, (2), (3), 4, 5] vs [{5}, 1, 2, 9, 3, 7]

1是LCS的成员,因此我们必须插入55位于原始序列中,因此我们记录了一个移动:MOVE 4 to 0

[5, {(1)}, (2), (3), 4] vs [5, {1}, 2, 9, 3, 7]

项目是相同的,所以我们继续下一个:

[5, (1), {(2)}, (3), 4] vs [5, 1, {2}, 9, 3, 7]

同样数字是相同的 - 转到下一个:

[5, (1), (2), {(3)}, 4] vs [5, 1, 2, {9}, 3, 7]

3是LCS的成员,因此我们必须插入9。原始元素没有9,因此它只是一个简单的插入:INSERT 9 at 3

[5, (1), (2), 9, {(3)}, 4] vs [5, 1, 2, 9, {3}, 7]

然而,数字是相同的 - 转到下一个:

[5, (1), (2), 9, (3), {4}] vs [5, 1, 2, 9, 3, {7}]

'4'不是LCS的成员,因此会被删除:DEL at 5

[5, (1), (2), 9, (3)] vs [5, 1, 2, 9, 3, {7}]

我们到达了第一个序列的末尾 - 我们只是将第二个序列的剩余项添加到第一个序列中,注意先前删除的列表。例如,如果先前删除了7,我们会在此时将该删除转换为移动。但由于原始列表没有7,我们会记录最终操作:INS 7 at 5