/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

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