longest-common.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package utils
  3. import (
  4. "fmt"
  5. "math"
  6. )
  7. var _ = fmt.Print
  8. func slice_iter(strs []string) func() (string, bool) {
  9. i := 0
  10. limit := len(strs)
  11. return func() (string, bool) {
  12. if i < limit {
  13. i++
  14. return strs[i-1], false
  15. }
  16. return "", true
  17. }
  18. }
  19. // Prefix returns the longest common prefix of the provided strings
  20. func Prefix(strs []string) string {
  21. return LongestCommon(slice_iter(strs), true)
  22. }
  23. // Suffix returns the longest common suffix of the provided strings
  24. func Suffix(strs []string) string {
  25. return LongestCommon(slice_iter(strs), false)
  26. }
  27. func min(a ...int) int {
  28. ans := math.MaxInt
  29. for _, x := range a {
  30. if x < ans {
  31. ans = x
  32. }
  33. }
  34. return ans
  35. }
  36. func LongestCommon(next func() (string, bool), prefix bool) string {
  37. xfix, done := next()
  38. if xfix == "" || done {
  39. return ""
  40. }
  41. for {
  42. q, done := next()
  43. if done {
  44. break
  45. }
  46. q_len := len(q)
  47. xfix_len := len(xfix)
  48. max_len := min(q_len, xfix_len)
  49. if max_len == 0 {
  50. return ""
  51. }
  52. if prefix {
  53. for i := 0; i < max_len; i++ {
  54. if xfix[i] != q[i] {
  55. xfix = xfix[:i]
  56. break
  57. }
  58. }
  59. } else {
  60. for i := 0; i < max_len; i++ {
  61. xi := xfix_len - i - 1
  62. si := q_len - i - 1
  63. if xfix[xi] != q[si] {
  64. xfix = xfix[xi+1:]
  65. break
  66. }
  67. }
  68. }
  69. }
  70. return xfix
  71. }