Declaration: Here is the original paper link . It is written by Eugene W. Myers at 1986. I (j_now. You may also call me cydooc) translated parts of the thesis in to Chinese with a few annotations. If it offends your copyright, please leave me a message. I will remove this post ASAP. Thanks.
Myers Diff Algorithm
Constant MAX ∈ [0,M+N]
Var V: Array [−MAX .. MAX] of Integer
V[1] ← 0
For D ← 0 to MAX Do
For k ← −D to D in steps of 2 Do
If k = −D or k ≠ D and V[k − 1] < V[k + 1] Then
x ← V[k + 1]
Else
x ← V[k − 1]+1
y ← x − k
While x < N and y < M and a x + 1 = by + 1 Do (x,y) ← (x+1,y+1)
V[k] ← x
If x ≥ N and y ≥ M Then
Length of an SES is D
Stop
Length of an SES is greater than MAX
Ruby Implementation
#!/usr/bin/env ruby
class V
def initialize(n, m, undefined_value)
@vn = []
@vm = []
@m = m
@n = n
@dv = undefined_value
end
def [](i)
ensure_size i
r = 0 > i ? @vm[-i-1] : @vn[i]
r ? r : @dv
end
def []=(i, value)
ensure_size i
if i < 0
@vm[-i-1] = value
else
@vn[i] = value
end
end
private
def ensure_size(i)
raise "#{i} is out of boundary, should be in [#{-@m}, #{@n}]" if -@m > i or @n < i
end
end
A = 'abcabba'
B = 'cbabac'
N = A.length
M = B.length
# v is an array of cordinate x. For the v[i], it means
# the max x cordinate in i-diagonal. i-diagonal is a
# set of vertexes that belongs to the line y = x - i.
v = V.new(N, M, -1)
v[1] = 0
done = nil
# A = 'abcabba'
# B = 'cbabac'
0.upto(N + M) do |d|
puts "Calculating #{d}-path: "
(-d).step(d, 2) do |k|
if k == -d or k != d and v[k-1] < v[k+1]
# (k+1)-path: move down from the k-path's end point
x = v[k+1]
direction = "move down"
else
# (k+1)-path: move right from the k-path's end point
x = v[k-1] + 1
direction = "move right"
end
puts " k: #{k}, x: #{x}. #{direction}."
y = x - k
# String is indexed from 0. So A[x] == B[y] is judging
# if the diagonal is a snake. i.e. A[x] == B[y] is the
# same meaning as the paper a[x + 1] = b[y + 1]
while x < N and y < M and A[x] == B[y]
x, y = x+1, y+1
puts " move along the diagonal (#{x-1}, #{y-1})->(#{x}, #{y})"
end
v[k] = x
if x >= N and y >= M
done = 1
break
end
end
break if done
end
Outputs
Calculating 0-path:
k: 0, x: 0. move down.
Calculating 1-path:
k: -1, x: 0. move down.
k: 1, x: 1. move right.
Calculating 2-path:
k: -2, x: 0. move down.
move along the diagonal (0, 2)->(1, 3)
move along the diagonal (1, 3)->(2, 4)
k: 0, x: 1. move down.
move along the diagonal (1, 1)->(2, 2)
k: 2, x: 2. move right.
move along the diagonal (2, 0)->(3, 1)
Calculating 3-path:
k: -3, x: 2. move down.
move along the diagonal (2, 5)->(3, 6)
k: -1, x: 3. move right.
move along the diagonal (3, 4)->(4, 5)
k: 1, x: 3. move down.
move along the diagonal (3, 2)->(4, 3)
move along the diagonal (4, 3)->(5, 4)
k: 3, x: 4. move right.
move along the diagonal (4, 1)->(5, 2)
Calculating 4-path:
k: -4, x: 3. move down.
k: -2, x: 4. move down.
k: 0, x: 5. move down.
k: 2, x: 6. move right.
move along the diagonal (6, 4)->(7, 5)
k: 4, x: 6. move right.
move along the diagonal (6, 2)->(7, 3)
Calculating 5-path:
k: -5, x: 3. move down.
k: -3, x: 4. move down.
k: -1, x: 5. move down.
k: 1, x: 7. move down.
Graphical Representation
Reference:
- Eugene W. Myers paper: An O(ND) Difference Algorithm and Its Variations
- Investigating Myers' diff algorithm
- See another post: Myers Diff paper -- 0