diff template library

5,036 views

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,036
On SlideShare
0
From Embeds
0
Number of Embeds
124
Actions
Shares
0
Downloads
4
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

diff template library

  1. 1. diff template library <ul><li>Tatsuhiko Kubo </li></ul><ul><li>http://d.hatena.ne.jp/cubicdaiya </li></ul>
  2. 2. 自己紹介 ・名前 : 久保 達彦 ・ HatenaID:cubicdaiya ・ twitter:@cubicdaiya ・ HP:http://cccis.jp ・職業 : プログラマ,時々サーバ管理者
  3. 3. diff template library とは <ul><li>拙作のdiffライブラリ(C++) </li></ul><ul><li>略してdtl </li></ul><ul><li>由来はC++のSTL(Standard Template Library </li></ul>
  4. 4. dtl-cpp <ul><li>http://code.google.com/p/dtl-cpp/ </li></ul>dtl という名前は既に使われていたので、 この名前に (_ _) プロジェクトページ
  5. 5. 今日の朝、最新版 (1.08) をリリースしました。
  6. 6. dtlの特徴(1) <ul><li>任意の型を持つ二つの要素列の差分が計算できる </li></ul><ul><li>Unified Formatが扱える </li></ul><ul><li>C++プログラムからdiff3が使える </li></ul><ul><li>C++プログラムからpatchが使える </li></ul>
  7. 7. dtlの特徴(2) <ul><li>修正BSDライセンス </li></ul><ul><li>ヘッダファイルのみで構成 </li></ul><ul><li>他のライブラリには極力依存しない </li></ul><ul><li>64bit対応済 </li></ul><ul><li>生のポインタ使ってます </li></ul>
  8. 8. とりあえず 使ってみよう
  9. 9. 二つの文字列の差分を取る
  10. 10. 二つの int 型配列の差分を取る
  11. 11. template によって要素と要素列という形で抽象化されるので、 いろんな場面で活用できる ・文字列 ( 文字の列 ) ・ int 型の配列 ( 数値の列 ) ・テキストファイル ( 文字列から成る行の列 ) ・ etc
  12. 12. 三つの文字列をマージする
  13. 13. 変更箇所が衝突した場合
  14. 14. patch
  15. 15. dtlの内部構造
  16. 16. そもそもDiffとは? <ul><li>Difference(違い、差分) </li></ul><ul><li>複数のファイル間の差分を取るプログラム </li></ul>
  17. 17. Diff を取るというのは、 <ul><li>Levenshtein Distance(編集距離) </li></ul><ul><li>LCS(Long Common Subsequence) </li></ul><ul><li>SES(Short Edit Script) </li></ul>↑ の 3 つを求めることと同義
  18. 18. A から B への変換を実現するための 要素の追加と削除の合計回数 2 つの要素列を A と B とする C: 共通 , D: 削除 , A: 追加 Levenstein Distance = A(n) + D(n) = 4 A(n) = 2, D(n) =2 Levenstein Distance abcdef -> acbedf C a D b C c D d A b C e A d C f
  19. 19. 2 つの要素列を A と B とする C: 共通 , D: 削除 , A: 追加 LCS = (C a) + (C c) + (C e) + (C f) = acef LCS A と B の最長共通部分列 abcdef -> acbedf C a D b C c D d A b C e A d C f
  20. 20. 2 つの要素列を A と B とする C: 共通 , D: 削除 , A: 追加 SES これ A から B への変換を 最小の編集回数で行うための手順 abcdef -> acbedf C a D b C c D d A b C e A d C f
  21. 21. エディットグラフ
  22. 22. エディットグラフ a b c d e f d a c f e a (0, 0) (M, N) x 軸 y 軸
  23. 23. <ul><li>y軸方向に+1進む(SESの「追加」) </li></ul><ul><li>x軸方向に+1進む(SESの「削除」) </li></ul><ul><li>y 軸と x 軸の対角線上に進む (SES の「共通」 ) </li></ul><ul><li>「共通」の場合のコストは 0 、それ以外は 1 </li></ul>
  24. 24. Diffとは
  25. 25. エディットグラフ上の点 (0, 0) から点 (M, N) (M=6, N=6) までの最短経路を求める問題 a b c d e f d a c f e a (0, 0) (M, N) x 軸 y 軸 コスト = 編集距離
  26. 26. 色んな Diff アルゴリズム <ul><li>動的計画法 </li></ul><ul><li>Myersのアルゴリズム </li></ul><ul><li>Wuのアルゴリズム </li></ul><ul><li>Gestalt Approach </li></ul>
  27. 27. 差分の計算はかなり重い処理なので効率的なアルゴリズムが必要
  28. 28. dtlにおける 差分の求め方
  29. 29. Wu のアルゴリズムを活用 <ul><li>SESにおける削除回数Pに注目 </li></ul><ul><li>エディットグラフにおける座標(M, N)までの最短経路をP=0から1ずつ増やしていって探索する </li></ul><ul><li>平均計算量はO(N+PD) </li></ul><ul><li>最悪でもO(NP) </li></ul>
  30. 30. D = Δ + 2P <ul><li>二つの要素列の長さをそれぞれ M, N とする </li></ul><ul><li>Δ = N - M (N >= M) </li></ul><ul><li>Dは編集距離 </li></ul><ul><li>PはSESにおける「削除」の合計数 </li></ul>
  31. 31. Δ = D a b c a b c d e f (3, 6) a (0, 0) Δ = 3
  32. 32. Δ ≠ D a b c d q q a b e f (0, 0) (4, 6) D=Δ の対角線からはみ出たらはみ出た分だけ戻ってこないといけない P Δ P
  33. 33. D=Δ+2P により、 探索範囲は以下のようになる (0, 0) (M, N) P Δ P ここまでが探索範囲
  34. 34. 探索の仕方
  35. 36. <ul><li>fp(k, p):P=pの時点で対角線k上における到達可能な最遠点 </li></ul><ul><li>snake(k ,y):P=pの時点で任意の点(x, y)から到達可能な最遠点のy座標を計算する関数 </li></ul><ul><li>k = y - x, pの初期値は0で1ずつ増やしていく </li></ul><ul><li>fp(k, p)=N の時点での p が SES の削除回数 P </li></ul>
  36. 37. 対角線k = y - x p (p, 0) k = -p p Δ k= Δ k= Δ+p (0, 0) (M, N) x y
  37. 38. Wu のアルゴリズムの実装例 <ul><li>http://github.com/cubicdaiya/onp </li></ul>
  38. 39. その他の機能の実装 について ちょこっと紹介
  39. 40. diff3の実装
  40. 41. dtlのマージ手順 1. 要素列 B と A の差分を取る (SES を SES_BA とする )2. 要素列 B と C の差分を取る (SES を SES_BC とする )3. SES_BA と SES_BC を先頭から比較していき、 A と C の変更点が組み合わされた要素列 S を生成する
  41. 42. patch の実装
  42. 43. patch は SES を使えば簡単 擬似コードです
  43. 44. <ul><li>google-diff-match-patch </li></ul><ul><li>LibXDiff(Gitで使われている) </li></ul>その他の diff ライブラリ
  44. 45. 参考文献 <ul><li>S.W.Maner, G.Myers, W.Miller, &quot;An O(NP) Sequence Comparison Algorithm&quot; </li></ul>
  45. 46. 最後に もし C++ で diff したくなったり、 必要になったら是非使ってみてください。 バグレポートやパッチも大歓迎↓ http://code.google.com/p/dtl-cpp [email_address]
  46. 47. ご静聴ありがとうございました

×