歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Git如何知曉文件差異

Git如何知曉文件差異

日期:2017/2/28 14:52:31   编辑:Linux教程

  求兩版本之間的差異是一個動態規劃問題

  git 能發現任何的改動,但它是怎麼發現的呢?難道它監控了我們對文件的讀寫操作? git 才沒這麼雞凍……它是通過比較新舊版本,掐指一算算出來的O(∩_∩)O。

  首先假設我們只能通過以下3個操作將舊版本演化為新版本:

copy —— 復制舊版本當前行到新版本

insert —— 在新版本中添加一行

delete —— 跳過舊版本當前行

  那麼,如下舊版本(左)到新版本(右):

1
22
333
1
333

可通過

方案一:copy、delete、copy

方案二:delete、delete、delete、insert、insert

演化而來。

  舊版本可通過這3個操作演化成任意一個新版本,即使新版本已經面目全非:

  假設舊版本有n行,新版本有m行。不管它們每行的內容是什麼,總是可以通過 n次delete 和 m次insert 演化出新版本。

  但是,由於 1個copy 能頂替 1個insert+1個delete,所以方案一比方案二少兩個步驟。而且我們實際進行的操作就是步驟最少的方案一(呵呵,人類是最聰明的O(∩_∩)O)。

--------------------------------------------------------------------------------

  現在我們有目標了:怎麼得到一個步驟最少的演化方案?為了更清晰地描述演化過程,我們定義兩個下標: i(舊版本行號)、j(新版本行號)。演化過程中會改變這兩個下標:

copy : ++i,++j

insert : ++j

delete : ++i

  定義 minPrice[i][j] 為從位置 (i,j) 演化到(n,m) 的最少步驟數(i,j從0開始);那麼,minPrice[0][0] 就是從舊版本演化到新版本的最少步驟數。

  求 minPrice 的遞歸式很容易得出:

--------------------------------------------------------------------------------

  如果照這個遞歸式寫一個遞歸算法,那麼遞歸算法會有很多重疊子問題,例如:

  minPrice[0][0]、minPrice[0][1]、minPrice[1][0] 都需要計算 minPrice[1][1]。

  因此適合采用動態規劃逆向求解。下面我用 java 實現了動態規劃版的 Diff:

E:\temp>java Diff src.txt dest.txt
1 1 1
2 - 22
3 2 333

E:\temp>

Copyright © Linux教程網 All Rights Reserved