Algorithm::Diff - 2��ゃ�勉����<�ゃ��/��ŝ�鴻�������с��'羂���勐�í�����'綏勛�違��羆������障�����
use Algorithm::Diff qw(diff sdiff LCS traverse_sequences
traverse_balanced);
@lcs = LCS( \@seq1, \@seq2 );
@lcs = LCS( \@seq1, \@seq2, $key_generation_function );
$lcsref = LCS( \@seq1, \@seq2 );
$lcsref = LCS( \@seq1, \@seq2, $key_generation_function );
@diffs = diff( \@seq1, \@seq2 );
@diffs = diff( \@seq1, \@seq2, $key_generation_function );
@sdiffs = sdiff( \@seq1, \@seq2 );
@sdiffs = sdiff( \@seq1, \@seq2, $key_generation_function );
traverse_sequences( \@seq1, \@seq2,
{ MATCH => $callback,
DISCARD_A => $callback,
DISCARD_B => $callback,
} );
traverse_sequences( \@seq1, \@seq2,
{ MATCH => $callback,
DISCARD_A => $callback,
DISCARD_B => $callback,
},
$key_generation_function );
traverse_balanced( \@seq1, \@seq2,
{ MATCH => $callback,
DISCARD_A => $callback,
DISCARD_B => $callback,
CHANGE => $callback,
} );
(by Mark-Jason Dominus)
腱���壚札������diff
��勌�������˨����c�〠�吾��������荐�篋����茯㏍����������������������障��;綵若���� 罩c�������≪�˨�眼�ŝ�����荀���ゃ��������������紊у����☗�眼�������������c�⓾����障��������
腱���壠充������篏����筝������������勉��'�����桁�演�����������(=longest common subsequence)'羈� ��с�������������c�⓾����障��(��������˨�ゃ����⓾�壔����障����ŭ拭�����ŝ����勉�с��������������腱���� ���������������������������������絽���������⓾����障��)���LCS��勐�馹���с�壔�� 2��ゃ�勤��膣���激�若�宴�潟�鴻�������c�⓾�������������障��:
a b c d f g h j q z
a b c d e f g i j k r x y z
��������☖検��鴻�勐����勉�激�若�宴�潟�鴻�����������綺���х憗��������荀�膣���勖�������激���������������「����������� �����c�⓾����障�������ゃ�障����������ŝ����壔����������勉�激�若�宴�潟�鴻�������������ゃ����勤��膣������������� 2��ɾ�勉�勉�激�若�宴�潟�鴻�����篁���勤��膣������������������˨����c�☗����������������違�������激�若�宴�潟�� S���荀���ゃ����������������c�⓾����障�������障�������ŝ�����S��壔�с�������������激������������� �����c�⓾����障�������������с��S��
a b c d f g j z
��˨�ŝ����障�����
������������diff��í�ゃ�壔�ɱ�阪�����緇������勉�壔����祉����勉�<����c����с��:
e h i k q r x y
+ - + + - + + +
�����勉�≪�吾�ャ�若�˨��LCS��勐�馹����茹f浦�����障��������������diff
��í�ゃ�壔�ɱ�阪����� ��������������∽�違��筝�膩������ャ�c�⓾����障�����
鐚���ゃ�勉�激�若�宴�潟�鴻��LCS��壠幻��̹��絽吾�����腆冴�ŝ����勉�������������������������障�������� �����������������ゃ�с����������с�壔�������障����������鴻��2��ゃ�勉�ŝ�鴻�����荀�膣���勛弘���菴������� ��医����������c�⓾�������翫����˨�壔��箴������遺札筝���勉�������ŝ�宴�若�鴻����������⓾�帥�⓾��������������
a x b y c z p d q
a b c a x b y c z
���膣���ŝ�≪����㏍�若����壔��篁ヤ����勉�������������激�若�宴�潟�鴻�勐����㏍�˨�����a
���b
��������� �����������潟�違����壔����������������������с��������鐚�
a x b y c z p d q
a b c a b y c z
��������˨�������演�����������a b c z
���荀���ゃ�������障��������������絎������˨�壔��LCS�� a x b y c z
��˨�ŝ����障��:
a x b y c z p d q
a b c a x b y c z
�����勉�≪�吾�ャ�若�˨��3��ゃ�勉����壔�鴻����若���櫝�純�ʒ�∽�違�����箴������障�����������������膂≦����ʒ���� 茯㋛�������障��: LCS
, diff
, sdiff
, traverse_sequences
, ��������� traverse_balanced
�����
荀�膣���勉�ŝ�鴻����吾�勉�ŝ����<�㋘�潟�鴻��2��ゆ検���������LCS��壔����������勖����桁�演����������� (=longest common subsequence)�����ャ�c�����������菴������障�������鴻�˨�í�若�祉�潟�潟����㏍�鴻����с�壔�� ��������壔����勉�������ŝ�ŝ�鴻����吾�勉�ŝ����<�㋘�潟�鴻��菴������障�����
@lcs = LCS( \@seq1, \@seq2 );
$lcsref = LCS( \@seq1, \@seq2 );
LCS
��˨�壔�ŝ����激�с�潟��3��ɾ�勉�勉����í�<�若�帥��羝<�������������堺�ャ�障��;�������� ��㏍�主�������∽�違�吾��CODE��ŝ����<�㋘�潟�鴻�с�����"KEY GENERATION FUNCTIONS"��� ���荀с��������������
@lcs = LCS( \@seq1, \@seq2, $keyGen );
$lcsref = LCS( \@seq1, \@seq2, $keyGen );
������菴遵����勉����í�<�若�帥����������違����㏍�主�������˨�若����潟��羝<�������障�����
@diffs = diff( \@seq1, \@seq2 );
$diffs_ref = diff( \@seq1, \@seq2 );
diff
��壔����������勉�激�若�宴�潟�鴻��2��ɾ�勉�勉����勉��紊������������������勖��絨��� 菴遵����������喝����ゃ�勰��������荐�膊������������������勐����眼�˨�ゃ����⓾�勤ą������菴������障����� �����勤ą������hunk��勉�ŝ�鴻����˨�ŝ����障��鐚����hunk鐚���������障��鐚��� 菴遵����������ゃ����������壠����眼����������鴻����g����������祉�壔�激�с�潟��茵������障����� diff
��勖�祉����ゃ��hunk��勉�ŝ�鴻����с�������鴻�˨�í�若�祉�潟�潟����㏍�鴻����с�壔�� �����勉�������ŝ�ŝ�鴻����吾�勉�ŝ����<�㋘�潟�鴻�˨�ŝ����障�����
篁ヤ����˩�����腓冴����障��: 篁ヤ�����2��ゃ�勉�激�若�宴�潟�鴻��diff���羆������障��:
a b c e h j l m n p
b c d e f j k l m r s t
腟����:
[
[ [ '-', 0, 'a' ] ],
[ [ '+', 2, 'd' ] ],
[ [ '-', 4, 'h' ] ,
[ '+', 4, 'f' ] ],
[ [ '+', 6, 'k' ] ],
[ [ '-', 8, 'n' ],
[ '-', 9, 'p' ],
[ '+', 9, 'r' ],
[ '+', 10, 's' ],
[ '+', 11, 't' ],
]
]
��������с��5��ゃ��hunk�����������障��������������hunk��壩�������勉�激�若�宴�潟�鴻�勌��臀�0��˨����� a
��壠�����(-
)��������ŝ�������違�ŝ����ŝ����◑����c�⓾����障�����2��ɾ�勉��hunk�� 2��ɾ�勉�勉�激�若�宴�潟�鴻�勌��臀�2��с��d
�����水��(+
)��������ŝ�������違�ŝ����ŝ���� 荐���c�⓾����障�����3��ɾ�勉��hunk��壩�������勉�激�若�宴�潟�鴻�勌��臀�4��˨�����h
��壠����ゃ�������� 2��ɾ�勉�勉�激�若�宴�潟�鴻�勌��臀�4���f
��х舟�����������������ŝ�������違�ŝ����ŝ���� 荐���c�⓾����障�����篁����2��ゃ��hunk������罕���с�����
diff
��˨�壔�ŝ����激�с�潟��3��ɾ�勉�勉����í�<�若�帥��羝<�������������堺�ャ�障��; ��㏍�主�������∽�違�吾��CODE��ŝ����<�㋘�潟�鴻�с�����"KEY GENERATION FUNCTIONS"��� ���荀с��������������
������菴遵����勉����í�<�若�帥����������違����㏍�主�������˨�若����潟��羝<�������障�����
@sdiffs = sdiff( \@seq1, \@seq2 );
$sdiffs_ref = sdiff( \@seq1, \@seq2 );
sdiff
��壔��Unix��⓾�若����c�ŝ����c�� sdiff�����������������˨�� 2��ゃ�勉�激�若�宴�潟�鴻����������������勖��絨������勰��������筝⓾�鴻�☀;腓冴������������� 綽�荀���ɱ����⓾�勰��������荐�膊������障��:
same same
before | after
old < -
- > new
��������奝�������ŝ����<�㋘�潟�鴻�勉�ŝ�鴻�����菴���������������������虁;腓阪�巡擦��勰�������� 腓冴����障�������鴻�˨�í�若�祉�潟�潟����㏍�鴻����с�壔�������勉�������ŝ�ŝ�鴻����吾� ��ŝ����<�㋘�潟�鴻��菴������障�����
茵◐ず��巡擦���3��ゃ�勤��膣���ф�������������障��:篆勰﹅���腓阪��(+
: 荀�膣�菴遵��, -
: 荀�膣������� u
: 荀�膣�紊���眼�ŝ��, c
: 荀�膣�紊����)�������𡉴��荀�膣��� ��違�����荀�膣���勐�ゃ��筝⓾����ц;腓冴�������障�����
篁ヤ�����2��ゃ�勉�激�若�宴�潟�鴻��sdiff
���:
a b c e h j l m n p
b c d e f j k l m r s t
篁ヤ����勉�������˨�ŝ����障��
[ [ '-', 'a', '' ], [ 'u', 'b', 'b' ], [ 'u', 'c', 'c' ], [ '+', '', 'd' ], [ 'u', 'e', 'e' ], [ 'c', 'h', 'f' ], [ 'u', 'j', 'j' ], [ '+', '', 'k' ], [ 'u', 'l', 'l' ], [ 'u', 'm', 'm' ], [ 'c', 'n', 'r' ], [ 'c', 'p', 's' ], [ '+', '', 't' ] ]
sdiff
��˨�壔�ŝ����激�с�潟��3��ɾ�勉�勉����í�<�若�帥��羝<�������������堺�ャ�障��; ��㏍�主�������∽�違�吾��CODE��ŝ����<�㋘�潟�鴻�с�����"KEY GENERATION FUNCTIONS"��� ���荀с��������������
������菴遵����勉����í�<�若�帥����������違����㏍�主�������˨�若����潟��羝<�������障�����
traverse_sequences
��壔�������勉�≪�吾�ャ�若�˨�ф��箴���������⓾�����������羆���◐���� �����<�激�ŝ����c�с��;diff
��� LCS
��壔�������������若�吟��������絎�茖���������⓾����障�����
2��ゃ�勛�≪�������������勉�◑�������⓾�����������������A��壔�激�若�宴�潟��A��勤��膣����������������B�� ��激�若�宴�潟��B��勤��膣������������障��������������筝≧�鴻�勛�≪�壔�������������勉�激�若�宴�潟�鴻�勐����㏍� 荀�膣������������⓾����障�����traverse_sequences
��壔��鐚������̥�≪����激�若�宴�潟�鴻�勤��膣�鐚���ゃ�� ��蚊�����������罸������⓾�若�吟�若�����絎���������潟�若�˨�������奝�∽�違����若�喝�冴����ŝ�������� ��蚊����障�����traverse_sequences
���絎�茵������⓾��������筝㏍�с�����A���$A[$i]
���腓冴��������B���$B[$j]
���腓冴����⓾��������������������������膈�������LCS��勰�������с�������� ������荀�膣�$A[$i]
���$B[$j]
�����������違�������勉�������̹�蚊����障����� �����������榊�����������������traverse_sequences
���MATCH
��潟�若�˨�������奝�∽�違����若�喝�冴����� 筝≧�鴻�勛�≪����蚊����障�����
��������с�ŝ�������違�������勉�激�若�宴�潟�鴻�с����í�<�������勛�≪��LCS��勰�������с�壔�ŝ��荀�膣������������⓾����障����� traverse_sequences
��夌�≪����蚊�����DISCARD_A
������������DISCARD_B
��潟�若�˨�������壔�� ��若�喝�冴����障�����������筝≧�鴻�勛�≪��LCS��勰�������с�ŝ�������違��traverse_sequences
�� ��í�<�����筝���鴻����蚊�����絲上����������潟�若�˨�������壔����若�喝�冴����障�������������������í�<�������若�違����� �����壩��絎���������障��������
traverse_sequences
��壔��罎�荐若�����2��ゃ�勉�激�若�宴�潟�鴻����潟�若�˨�������奝�∽�違�����絎������� ��������激�ャ�с�����篁ヤ����勉�������˨�ŝ����障��;
traverse_sequences( \@seq1, \@seq2,
{ MATCH => $callback_1,
DISCARD_A => $callback_2,
DISCARD_B => $callback_3,
} );
MATCH, DISCARD_A, ��������� DISCARD_B��勉�������勉�潟�若�˨�������壔�壔�� 絨���ŝ��������2��ゃ�勛�≪�勉�ゃ�潟�������壔�鴻��綣���違�������〠����c�☗�若�喝�冴�������障����� �����������壠�ゃ��菴������������壠��������緇���������⓾����障�������������������勉����若����˨����� ��潟�若�˨�������壔����������ャ����������違����������壠�若�違����障��������
A_FINISHED ��� B_FINISHED��勉�������勉�潟�若�˨�������壔�壠����ŝ��������絲上��������A��障�����B�� ��ゃ�潟�������壔�剛�������у�若�喝�冴�������障�����
���������B�����������ŝ�������˨�����A��������勉�激�若�宴�潟�鴻�勖��緇���˨�ŝ�c�������� traverse_sequences
��壔�����B�����蚊�������������������������勉�������ʒ�∽�違����������違�� A_FINISHED
��潟�若�˨�������壔����������с�ŝ�������遺撮���������DISCARD_B
��� ��若�喝�冴����障��������������B��������̥����c�⓾�����罕���с����� traverse_sequences
��壚検��鴻�勛�≪�������������������勐嚳綽���������激�若�宴�潟�鴻�勛���������� ��ŝ�c����������˨�ŝ�帥�若�潟����障��������������������true���紊掩�����������false���菴������障����� �憜����壚�����紊掩����������������壔�������障��������
traverse_sequences
��˨�壔�ŝ����激�с�潟��3��ɾ�勉�勉����í�<�若�帥��羝<�������������堺�ャ�障��; ��㏍�主�������∽�違�吾��CODE��ŝ����<�㋘�潟�鴻�с�����"KEY GENERATION FUNCTIONS"��� ���荀с��������������
������菴遵����勉����í�<�若�帥����������違����㏍�主�������˨�若����潟��羝<�������障�����
traverse_balanced
���traverse_sequences
��勌撮�����������ŝ����障����� 荐�膊����������LCS��с�勤��膣������������☎弘���菴������������̥�違�ŝ����≪�˨�眼�ŝ�冴�������ñ�������障����� 筝���≪�����腦���������������水�ャ�������ゃ�������ц��膣���勐����眼��腓冴��篁c�������˨��2��ゃ�勉�激�若�宴�潟�拷����� ������緇������̹����潟��筝���鴻�с�壠����ゃ�с��������筝���鴻�х�榊�������������ゃ�勐�������˨�����筝���鴻�勖�水�ャ�� 膓�������紊���雁�������怨�������障�����
���������traverse_sequences
��˨����c�⓾�泣����若����������⓾����� DISCARD_A
, DISCARD_B
, �������� MATCH
��潟�若�˨�������壔����������⓾��traverse_balanced
��壔��鐚���ゃ�勤��膣�������篁���勉����勉�˨����c� 臀勖��
��������⓾��������������腓冴��CHANGE
��潟�若�˨�������壔����泣����若�������障�����
traverse_sequences( \@seq1, \@seq2,
{ MATCH => $callback_1,
DISCARD_A => $callback_2,
DISCARD_B => $callback_3,
CHANGE => $callback_4,
} );
CHANGE
������絎���������ŝ�������違��traverse_balanced
��壔��
CHANGE
��ゃ����潟�����DISCARD_A
���DISCARD_B
��≪�壔�激�с�潟��絲上��篁������障����� �����勛����������ゃ����潟����勰����ŝ�������c�����traverse_sequences
�����������������˨�ŝ����障�����
traverse_balanced
���traverse_sequences
���������紊ч����勉����若�帥����☎�������⓾����� ��������˨����������������������������<����c����������������������������障��������
�����勉�≪�吾�ャ�若�˨��sdiff
��∽�違�壔��traverse_balanced
�����若�吟��������絎�茖��������� �����障�����
鐚���㏍�主�������∽�逸��
diff
, LCS
, ��������� traverse_sequences
��壩��緇���˨�ŝ����激�с�潟�勉����í�<�若�帥�� ��������������障�������������壚��������������荀�膣����筝������̬����ャ��������絖�������菴���������㏍�主�����鐚��� �����激�ワ����∽�違�吾��CODE��ŝ����<�㋘�潟�鴻�с����� 鐚�������篁ュ����壔����������ŝ�������̩��2��ゃ�勤��膣���������������◑����������������翫����˨�壔�� �����������勉�㏍�若�壠�������с�ŝ�������違�ŝ����障�����篏������㏍�主�������∽�違�����箴���������ŝ�������違�� �����勉�㏍�若�壩��絖������������⓾�勉����勤��膣���˨�ŝ����障�����
��������í�˨����с�壔��罸�莠����"eq"���篏帥�������������í�˨����勖��絖�������羲�膊�絖�'""'���篏帥�c� ��㏍�若�˨�������障�����
������������荀���˨�ŝ����勉�壩��絖����篁ュ����勉����勉��罸�莠���������������с����� ��������������◑����������������違�ŝ��茲���違�勉�ŝ����吾�с�壔����������c�⓾�������翫�������㏍�主�������∽�違�� ���箴�������綽�荀������������障�������������с�ŝ�������違�������������⓾����若�壔�ŝ�ŝ����<�㋘�潟�鴻�ф����� ��������⓾��������������腆阪����˨����ŝ�������違�ŝ����障��������
箴������違��篁ヤ����勌����ゃ����⓾�̬�������⓾�帥�⓾�����������:
package Person;
sub new
{
my $package = shift;
return bless { name => '', ssn => '', @_ }, $package;
}
sub clone
{
my $old = shift;
my $new = bless { %$old }, ref($old);
}
sub hash
{
return shift()->{'ssn'};
}
my $person1 = Person->new( name => 'Joe', ssn => '123-45-6789' );
my $person2 = Person->new( name => 'Mary', ssn => '123-47-0000' );
my $person3 = Person->new( name => 'Pete', ssn => '999-45-2222' );
my $person4 = Person->new( name => 'Peggy', ssn => '123-45-9999' );
my $person5 = Person->new( name => 'Frank', ssn => '000-45-9999' );
������篁ヤ����勉�������˨��������:
my $array1 = [ $person1, $person2, $person4 ];
my $array2 = [ $person1, $person3, $person4, $person5 ];
Algorithm::Diff::diff( $array1, $array2 );
�����鴻�⓾��罩e幻������篏���������с��������(�����ŝ����吾�с�壔����壩��莠���勉����� "Person=HASH(0x82425b0)"��勉�������ʋ��絖�������紊������������障��鐚����
���������篁ヤ����勉�������˨��������:
my $array1 = [ $person1, $person2, $person4 ];
my $array2 = [ $person1, $person3, $person4->clone(), $person5 ];
Algorithm::Diff::diff( $array1, $array2 );
$person4 ���$person4->clone()���(������name���SSN��������c�⓾����障��鐚���壔����違�ŝ�� ��ŝ����吾�с�壔����������☀����������障��������������膈���◑����〠⓲��������勉�с�������違�� �����ŝ����壔�㏍�主�������∽�違��羝<����ŝ�������違�������障�����:
my $array1 = [ $person1, $person2, $person4 ];
my $array2 = [ $person1, $person3, $person4->clone(), $person5 ];
Algorithm::Diff::diff( $array1, $array2, \&Person::hash );
��������壠��Person��с��'ssn'�����c�若�˨�����罸�莠���㏍�若�������☖戎�����障����������勉����� $person4 ��� $person4->clone()�����������◑�������障�����
�����ŝ�������������違��菴遵����勉����í�<�若�帥����㏍�主�������∽�違��羝<�������������с����障�����
�����勉����若�吾�с�潟�� Ned Konz, perl@bike-nomad.com ��˨����c�☖����������⓾����障�����
Copyright (c) 2000-2002 Ned Konz. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
�����若�吾�с��0.59��障�э����������⓾�������勉����㏍�ャ�<�潟����勐ぇ���鐚���
Mark-Jason Dominus, mjd-perl-diff@plover.com
��˨����c�〠�吾�������⓾����障��鐚�
�����勉����若�吾�с�潟�с�������㏍�ャ�<�潟�������˨�若����潟�勐��������Mark-Jason��勉����勉����� ��������⓾����⓾����障��������������Diff.pm��勉�潟�若����壠����������違�������ŝ�c�⓾����障�����
�����勉�潟�若�����Mario Wolczko <mario@wolczko.com>���Smalltalk��潟�若����� ��ñ����������⓾����障�������������壚札筝����URL��у��緇������������������堺�ャ�障��鐚� ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
sdiff
��������� traverse_balanced
���Mike Schilli <m@perlmeister.com>��˨����c�〠�吾�������障��������
��≪�˨�眼�ŝ�冴���� A Fast Algorithm for Computing Longest Common Subsequences, CACM, vol.20, no.5, pp.350-353, May 1977,��с����鴻����若�������劫���������������� 絨������ʋ�拷����鴻����������̬ą�����������⓾����障�����