diff template library

47
diff template library Tatsuhiko Kubo http://d.hatena.ne.jp/cubicdaiya

Upload: daisuke-nikura

Post on 30-Jun-2015

4.740 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: diff template library

diff template libraryTatsuhiko Kubo

http://d.hatena.ne.jp/cubicdaiya

Page 2: diff template library

自己紹介

・名前 : 久保 達彦・ HatenaID:cubicdaiya・ twitter:@cubicdaiya・ HP:http://cccis.jp・職業 : プログラマ,時々サーバ管理者

Page 3: diff template library

diff template libraryとは

•拙作の diff ライブラリ (C++)

•略して dtl

•由来は C++ の STL(Standard Template Library

Page 4: diff template library

dtl-cpphttp://code.google.com/p/dtl-cpp/

dtl という名前は既に使われていたので、この名前に (_ _)

プロジェクトページ

Page 5: diff template library

今日の朝、最新版(1.08) をリリースしま

した。

Page 6: diff template library

dtl の特徴 (1)

•任意の型を持つ二つの要素列の差分が計算できる

•Unified Format が扱える

•C++ プログラムから diff3 が使える

•C++ プログラムから patch が使える

Page 7: diff template library

dtl の特徴 (2)

•修正 BSD ライセンス

•ヘッダファイルのみで構成

•他のライブラリには極力依存しない

•64bit 対応済

•生のポインタ使ってます

Page 8: diff template library

とりあえず使ってみよう

Page 9: diff template library

二つの文字列の差分を取る

Page 10: diff template library

二つの int 型配列の差分を取る

Page 11: diff template library

template によって要素と要素列という形で抽象化されるので、

いろんな場面で活用できる

・文字列 ( 文字の列 )・ int 型の配列 ( 数値の列 )・テキストファイル ( 文字列から成る行の列 )・ etc

Page 12: diff template library

三つの文字列をマージする

Page 13: diff template library

変更箇所が衝突した場合

Page 14: diff template library

patch

Page 15: diff template library

dtl の内部構造

Page 16: diff template library

そもそも Diff とは?

•Difference( 違い、差分 )

•複数のファイル間の差分を取るプログラム

Page 17: diff template library

Diff を取るというのは、

•Levenshtein Distance( 編集距離 )

•LCS(Long Common Subsequence)

•SES(Short Edit Script)

↑ の 3 つを求めることと同義

Page 18: diff template library

A から B への変換を実現するための要素の追加と削除の合計回数

2 つの要素列を A と B とするabcdef → acbedf C a D b C c D d A b C e A d C f

C: 共通 , D: 削除 , A: 追加

Levenstein Distance = A(n) + D(n) = 4

A(n) = 2, D(n) =2

Levenstein Distance

Page 19: diff template library

2 つの要素列を A と B とするabcdef → acbedf C a D b C c D d A b C e A d C f

C: 共通 , D: 削除 , A: 追加 LCS = (C a) + (C c) + (C e) + (C f) = acef

LCS

A と B の最長共通部分列

Page 20: diff template library

2 つの要素列を A と B とするabcdef → acbedf C a D b C c D d A b C e A d C f

C: 共通 , D: 削除 , A: 追加

SES

これ

A から B への変換を最小の編集回数で行うための手順

Page 21: diff template library

エディットグラフ

Page 22: diff template library

エディットグラフ

a

b

c

d

e

f

d a c f e a(0, 0)

(M, N)

x 軸

y 軸

Page 23: diff template library

•y 軸方向に +1 進む (SES の「追加」 )

•x 軸方向に +1 進む (SES の「削除」 )

• y 軸と x 軸の対角線上に進む (SES の「共通」 )

• 「共通」の場合のコストは 0 、それ以外は 1

Page 24: diff template library

Diff とは

Page 25: diff template library

a

b

c

d

e

f

d a c f e a(0, 0)

(M, N)

x 軸

y 軸

エディットグラフ上の点 (0, 0) から点 (M, N) (M=6, N=6) までの最短経路を求める問題

コスト = 編集距離

Page 26: diff template library

色んな Diff アルゴリズム

•動的計画法

•Myers のアルゴリズム

•Wu のアルゴリズム

•Gestalt Approach

Page 27: diff template library

差分の計算はかなり重い処理なので効率的なアルゴリズムが必要

Page 28: diff template library

dtl における差分の求め方

Page 29: diff template library

Wu のアルゴリズムを活用

•SES における削除回数 P に注目

•エディットグラフにおける座標 (M, N)までの最短経路を P=0 から 1 ずつ増やしていって探索する

•平均計算量は O(N+PD)

•最悪でも O(NP)

Page 30: diff template library

D = Δ + 2P

•二つの要素列の長さをそれぞれ M, N とする

•Δ = N - M (N >= M)

•D は編集距離

•P は SES における「削除」の合計数

Page 31: diff template library

Δ = D

a

b

c

a b c d e f

(3, 6)

a(0, 0)

Δ = 3

Page 32: diff template library

Δ ≠ D

a

b

c

d

q q a b e f(0, 0)

(4, 6)D=Δ の対角線からはみ出たらはみ出た分だけ戻ってこないといけない

P

Δ

P

Page 33: diff template library

D=Δ+2P により、探索範囲は以下のようになる

(0, 0)

(M, N)

P

Δ P

ここまでが探索範囲

Page 34: diff template library

探索の仕方

Page 35: diff template library
Page 36: diff template library

•fp(k, p) : P=p の時点で対角線k上における到達可能な最遠点

•snake(k ,y) : P=p の時点で任意の点(x, y) から到達可能な最遠点の y 座標を計算する関数

•k = y - x, p の初期値は 0 で 1 ずつ増やしていく

•fp(k, p)=N の時点での p が SES の削除回数 P

Page 37: diff template library

対角線 k = y - x

p(p, 0)

k = -p

k= Δ

k= Δ+p

(0, 0)

(M, N)x

y

Page 38: diff template library

Wu のアルゴリズムの実装例http://github.com/cubicdaiya/onp

Page 39: diff template library

その他の機能の実装についてちょこっと紹介

Page 40: diff template library

diff3 の実装

Page 41: diff template library

dtl のマージ手順

1. 要素列 B と A の差分を取る (SES を SES_BA とする )2. 要素列 B と C の差分を取る (SES を SES_BC とする )3. SES_BA と SES_BC を先頭から比較していき、A と C の変更点が組み合わされた要素列 S を生成する

Page 42: diff template library

patch の実装

Page 43: diff template library

patch は SES を使えば簡単

擬似コードです

Page 44: diff template library

•google-diff-match-patch

•LibXDiff(Git で使われている )

その他の diff ライブラリ

Page 45: diff template library

参考文献

•S.W.Maner, G.Myers, W.Miller, "An O(NP) Sequence Comparison Algorithm"

Page 46: diff template library

最後に

もし C++ で diff したくなったり、必要になったら是非使ってみてください。

バグレポートやパッチも大歓迎↓

http://code.google.com/p/dtl-cpp

[email protected]

Page 47: diff template library

ご静聴ありがとうございました