Существует ли алгоритм-подобный diff, который обрабатывает движущиеся блоки строк?

Программа diffв ее различных воплощениях довольно хорошо вычисляет разницу между двумя текстовыми файлами и выражает ее более компактно, чем показывает оба файла целиком. Он показывает разницу в виде последовательности вставленных и удаленных кусков строк (или измененных строк в некоторых случаях, но это эквивалентно удалению, за которым следует вставка). Одна и та же или очень похожая программа или алгоритм используются patchи системами управления версиями для минимизации памяти, необходимой для представления различий между двумя версиями одного и того же файла. Алгоритм обсуждается здесь и здесь .

Но он падает, когда блоки текста перемещаются внутри файла.

Предположим, у вас есть следующие два файла, a.txtиb.txt(представьте, что они оба состоят из сотен строк, а не всего 6):

a.txt   b.txt
-----   -----
1       4
2       5
3       6
4       1
5       2
6       3

diff a.txt b.txtпоказывает это:

$ diff a.txt b.txt 
1,3d0
< 1
< 2
< 3
6a4,6
> 1
> 2
> 3

Изменение с a.txtна b.txtможет быть выражено как «Возьмите первые три строки и переместите их в конец», но diffпоказывает полное содержимое перемещенного фрагмента строк дважды, упуская возможность очень кратко описать это большое изменение.

Обратите внимание, что diff -eпоказывает блок текста только один раз, но это потому, что он не показывает содержимое удаленных строк.

Существует ли вариант алгоритма diff, в котором (a)сохраняет способность diffпредставлять вставки и удаления, а (b)эффективно представляет перемещенные блоки текста без показать все их содержимое?

48
задан Keith Thompson 8 April 2012 в 20:14
поделиться