algorithm – Diff两个标识符序列

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

操作可以是:

>在给定位置插入标识符
>从给定位置删除标识符
>将标识符从某个位置移动到另一个位置

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

例:

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

谢谢 !

最佳答案 首先找到
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的成员,所以我们必须插入5. 5是原始序列,所以我们记录一个移动:MOVE 4到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为5

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

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

点赞