golcs.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package lcs
  2. import (
  3. "reflect"
  4. )
  5. type Lcs interface {
  6. Values() (values []interface{})
  7. IndexPairs() (pairs []IndexPair)
  8. Length() (length int)
  9. Left() (leftValues []interface{})
  10. Right() (righttValues []interface{})
  11. }
  12. type IndexPair struct {
  13. Left int
  14. Right int
  15. }
  16. type lcs struct {
  17. left []interface{}
  18. right []interface{}
  19. /* for caching */
  20. table [][]int
  21. indexPairs []IndexPair
  22. values []interface{}
  23. }
  24. func New(left, right []interface{}) Lcs {
  25. return &lcs{
  26. left: left,
  27. right: right,
  28. table: nil,
  29. indexPairs: nil,
  30. values: nil,
  31. }
  32. }
  33. func (lcs *lcs) Table() (table [][]int) {
  34. if lcs.table != nil {
  35. return lcs.table
  36. }
  37. sizeX := len(lcs.left) + 1
  38. sizeY := len(lcs.right) + 1
  39. table = make([][]int, sizeX)
  40. for x := 0; x < sizeX; x++ {
  41. table[x] = make([]int, sizeY)
  42. }
  43. for y := 1; y < sizeY; y++ {
  44. for x := 1; x < sizeX; x++ {
  45. increment := 0
  46. if reflect.DeepEqual(lcs.left[x-1], lcs.right[y-1]) {
  47. increment = 1
  48. }
  49. table[x][y] = max(table[x-1][y-1]+increment, table[x-1][y], table[x][y-1])
  50. }
  51. }
  52. lcs.table = table
  53. return
  54. }
  55. func (lcs *lcs) Length() (length int) {
  56. length = lcs.Table()[len(lcs.left)][len(lcs.right)]
  57. return
  58. }
  59. func (lcs *lcs) IndexPairs() (pairs []IndexPair) {
  60. if lcs.indexPairs != nil {
  61. return lcs.indexPairs
  62. }
  63. table := lcs.Table()
  64. pairs = make([]IndexPair, table[len(table)-1][len(table[0])-1])
  65. for x, y := len(lcs.left), len(lcs.right); x > 0 && y > 0; {
  66. if reflect.DeepEqual(lcs.left[x-1], lcs.right[y-1]) {
  67. pairs[table[x][y]-1] = IndexPair{Left: x - 1, Right: y - 1}
  68. x--
  69. y--
  70. } else {
  71. if table[x-1][y] >= table[x][y-1] {
  72. x--
  73. } else {
  74. y--
  75. }
  76. }
  77. }
  78. lcs.indexPairs = pairs
  79. return
  80. }
  81. func (lcs *lcs) Values() (values []interface{}) {
  82. if lcs.values != nil {
  83. return lcs.values
  84. }
  85. pairs := lcs.IndexPairs()
  86. values = make([]interface{}, len(pairs))
  87. for i, pair := range pairs {
  88. values[i] = lcs.left[pair.Left]
  89. }
  90. lcs.values = values
  91. return
  92. }
  93. func (lcs *lcs) Left() (leftValues []interface{}) {
  94. leftValues = lcs.left
  95. return
  96. }
  97. func (lcs *lcs) Right() (rightValues []interface{}) {
  98. rightValues = lcs.right
  99. return
  100. }
  101. func max(first int, rest ...int) (max int) {
  102. max = first
  103. for _, value := range rest {
  104. if value > max {
  105. max = value
  106. }
  107. }
  108. return
  109. }