PageRenderTime 52ms CodeModel.GetById 22ms app.highlight 27ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/rubyfish/longest_substring.rb

https://github.com/gthole/rubyfish
Ruby | 95 lines | 74 code | 20 blank | 1 comment | 20 complexity | 077f0c7d900721646ef774934e93e1f8 MD5 | raw file
 1module RubyFish::LongestSubstring
 2
 3  # http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Longest_common_substring#Ruby
 4  def distance a, b, opts={}
 5  	ignore_case = opts[:ignore_case]
 6  	
 7    as = a.to_s
 8    bs = b.to_s
 9    
10    if ignore_case
11    	as.downcase!
12    	bs.downcase!
13    end
14
15    rows = as.size
16    cols = bs.size
17
18    if rows == 0 || cols == 0
19      return 0
20    end
21
22    num= ::RubyFish::MMatrix.new rows, cols
23    len,ans=0
24
25    as.each_char.with_index do |ac, i|
26      bs.each_char.with_index do |bc, j|
27        unless ac == bc
28          num[i, j]=0
29        else
30          (i==0 || j==0)? num[i, j] = 1 : num[i, j] = 1 + num[i-1, j-1]
31          len = ans = num[i, j] if num[i, j] > len
32        end
33      end
34    end
35
36    ans
37  end
38
39  def longest_substring a, b, opts={}
40  	ignore_case = opts[:ignore_case]
41  	
42    as = a.to_s
43    bs = b.to_s
44    
45    if ignore_case
46    	as.downcase!
47    	bs.downcase!
48    end
49
50    rows = as.size
51    cols = bs.size
52
53    res = ""
54    len = 0
55    last_sub = 0
56
57    if rows == 0 || cols == 0
58      return res
59    end
60
61    num = ::RubyFish::MMatrix.new rows, cols
62
63    as.each_char.with_index do |ac, i|
64      bs.each_char.with_index do |bc, j|
65        unless ac == bc
66          num[i, j] = 0
67        else
68          (i == 0 || j == 0)? num[i, j] = 1 : num[i, j] = 1 + num[i-1, j-1]
69          if num[i, j] > len
70            len = num[i, j]
71            this_sub = i
72            this_sub -= num[i-1, j-1] unless num[i-1, j-1].nil?
73            if last_sub == this_sub
74              res += as[i,1]
75            else
76              last_sub = this_sub
77              res = as[last_sub, (i+1) - last_sub]
78            end
79          end
80        end
81      end
82    end
83
84    res
85  end
86
87  def longest_substring_index(a, b, opts={})
88    a.index(longest_substring(a, b, :ignore_case => opts[:ignore_case]))
89  end
90
91  module_function :distance
92  module_function :longest_substring
93  module_function :longest_substring_index
94
95end