-
Notifications
You must be signed in to change notification settings - Fork 55
Expand file tree
/
Copy pathlcs.rb
More file actions
66 lines (60 loc) · 1.98 KB
/
lcs.rb
File metadata and controls
66 lines (60 loc) · 1.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
module DynamicProgramming
class LCS
class << self
# Internal: Find the length of the longest common subsequence of two strings
#
# x - First string
# y - Second string
#
# Examples
# LCS_length("ABCBDAB", "BDCABA")
#
def LCS_length(x, y)
m = x.length
n = y.length
b = Array.new(m+1) { Array.new(n+1) } # Trace array (CROSS, UP, LEFT)
c = Array.new(m+1) { Array.new(n+1) } # Index array (Tracks the length)
(0..m).each { |i| c[i][0] = 0 } # Initialze the first row and first
(0..n).each { |j| c[0][j] = 0 } # column to zero in the index array
(1..m).each do |i| # Index is started from 1 and ends at m
(1..n).each do |j| # to make the recursion smoother without
if x[i-1] == y[j-1] # trying to manipulate the first condition
c[i][j] = c[i-1][j-1] + 1
b[i][j] = "CROSS"
elsif c[i-1][j] >= c[i][j-1]
c[i][j] = c[i-1][j]
b[i][j] = "UP"
else
c[i][j] = c[i][j-1]
b[i][j] = "LEFT"
end
end
end
[c, b]
end
# Internal: Print the longest common subsequence of two strings
#
# b - Matrix array which has the trace with CROSS, UP and LEFT directions
# x - First string
# i - Last row in the trace array
# j - Last column in the trace array
# output - Stores the final subsequence of two strings
#
# Examples
# print_LCS("ABCBDAB", "BDCABA")
# => BCBA
#
def print_LCS(b, x, i, j, output="")
return output.reverse if ((i == 0) || (j == 0))
if b[i][j] == "CROSS"
output += x[i-1]
print_LCS(b, x, i-1, j-1, output)
elsif b[i][j] == "UP"
print_LCS(b, x, i-1, j, output)
else
print_LCS(b, x, i, j-1, output)
end
end
end
end
end