alex0sunny

common subarray

Sep 12th, 2021 (edited)
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.32 KB | None | 0 0
  1. Q = 10 ** 9 + 7
  2. R = 2 ** 32
  3.  
  4.  
  5. def get_base_hashes(a):
  6.     hashes = [0]
  7.     for v in a:
  8.         hashes.append((hashes[-1] * Q + v) % R)
  9.     return hashes
  10.  
  11.  
  12. def calc_hash(i, j, hashes):
  13.     start_part = hashes[i] * pow(Q, (j - i), R)
  14.     return (hashes[j] - start_part) % R
  15.  
  16.  
  17. def find_k_subseq(k, a, b, a_hashes, b_hashes):
  18.     for ia in range(len(a) - k + 1):
  19.         a_hash = calc_hash(ia, ia + k, a_hashes)
  20.         for ib in range(len(b) - k + 1):
  21.             b_hash = calc_hash(ib, ib + k, b_hashes)
  22.             if b_hash == a_hash:
  23.                 r = k
  24.                 for m in range(min(len(a) - ia - k, len(b) - ib - k)):
  25.                     if a[ia + k + m] != b[ib + k + m]:
  26.                         break
  27.                     r += 1
  28.                 return r
  29.     return 0
  30.  
  31.  
  32. def get_len(a, b):
  33.     if len(a) > len(b):
  34.         a, b = b, a
  35.     a_hashes = get_base_hashes(a)
  36.     b_hashes = get_base_hashes(b)
  37.     lo = 0
  38.     hi = len(a) + 1
  39.     while lo < hi - 1:
  40.         mid = (lo + hi) // 2
  41.         k = find_k_subseq(mid, a, b, a_hashes, b_hashes)
  42.         if k:
  43.             lo = k
  44.         else:
  45.             hi = mid
  46.     return lo
  47.  
  48.  
  49. a = [1, 2, 3, 4, 5]
  50. b = [4, 5, 9]
  51. assert (get_len(a, b) == 2)
  52.  
  53. a = [1, 2, 3, 2, 1]
  54. b = [3, 2, 1, 5, 6]
  55. assert (get_len(a, b) == 3)
  56.  
  57. assert (get_len([1], [1]) == 1)
  58.  
Add Comment
Please, Sign In to add comment