我來這裏尋找差異算法,然後做出我自己的實現。對不起,我不知道vcdiff。
Wikipedia:從一個最長的公共子序列,它只是一小步獲得不同樣的輸出:如果一個項目在子序列中不存在但存在於原始項目中,它必須已被刪除。 (下面的' - '標記。)如果它在子序列中不存在但是存在於第二序列中,則它必須已經添加。('+'標記。)
好的動畫LCS algorithm here。
鏈接到一個快速的LCS ruby implementation here。
我的緩慢和簡單的紅寶石適應如下。
def lcs(xs, ys)
if xs.count > 0 and ys.count > 0
xe, *xb = xs
ye, *yb = ys
if xe == ye
return [xe] + lcs(xb, yb)
end
a = lcs(xs, yb)
b = lcs(xb, ys)
return (a.length > b.length) ? a : b
end
return []
end
def find_diffs(original, modified, subsequence)
result = []
while subsequence.length > 0
sfirst, *subsequence = subsequence
while modified.length > 0
mfirst, *modified = modified
break if mfirst == sfirst
result << "+#{mfirst}"
end
while original.length > 0
ofirst, *original = original
break if ofirst == sfirst
result << "-#{ofirst}"
end
result << "#{sfirst}"
end
while modified.length > 0
mfirst, *modified = modified
result << "+#{mfirst}"
end
while original.length > 0
ofirst, *original = original
result << "-#{ofirst}"
end
return result
end
def pretty_diff(original, modified)
subsequence = lcs(modified, original)
diffs = find_diffs(original, modified, subsequence)
puts 'ORIG [' + original.join(', ') + ']'
puts 'MODIFIED [' + modified.join(', ') + ']'
puts 'LCS [' + subsequence.join(', ') + ']'
puts 'DIFFS [' + diffs.join(', ') + ']'
end
pretty_diff("human".scan(/./), "chimpanzee".scan(/./))
# ORIG [h, u, m, a, n]
# MODIFIED [c, h, i, m, p, a, n, z, e, e]
# LCS [h, m, a, n]
# DIFFS [+c, h, +i, -u, m, +p, a, n, +z, +e, +e]
RFC並不是要描述算法。它們旨在描述接口(/協議)。 – 2011-02-23 22:25:13
也許這會有所幫助:http://paulbutler.org/archives/a-simple-diff-algorithm-in-php/它確實很棒,它很小(只有29行**;它有2個功能)。它與Stack Overflow的編輯版本比較相似。 – Nathan 2012-12-24 04:35:06
VCDIFF不適用於人類可讀的差異。它採用添加,複製和運行指令,而不是由大多數純文本差異算法發出的更易於讀取的刪除和插入指令。對於VCDIFF,你需要像這裏描述的xdelta algortihm一樣的東西。http://www.xmailserver.org/xdfs.pdf – asgerhallas 2013-03-20 20:12:12