рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдЕрдзрд┐рдХрддрдо рд╕рд╛рдорд╛рдиреНрдп рдЕрдиреБрд╡рд░реНрддреА рдпрд╛ LCS (рд╕рдмрд╕реЗ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рд╕рд╛рдорд╛рдиреНрдп рдЕрдиреБрдХреНрд░рдо) рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реЛрдХрдкреНрд░рд┐рдп рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред рдЪреВрдВрдХрд┐ рдЬреЛрд░ рд╕реАрдЦрдиреЗ рдкрд░ рд╣реИ, рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрдкрдпреЛрдЧ рдкрд░ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкрд╛рдпрдерди рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рднрд╛рд╖рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдХреЛрдб рдХреА рдорд╛рддреНрд░рд╛ рдХрдо рд╣реЛ рдЬрд╛рдПрдЧреА рдФрд░ рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░реЛрдВ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдкрд░рд┐рднрд╛рд╖рд┐рдд
рдПрдХ рдЕрдиреБрдХреНрд░рдо рддрддреНрд╡реЛрдВ рдХрд╛ рдПрдХ рдХреНрд░рдордмрджреНрдз рд╕реЗрдЯ рд╣реИред рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдПрдХ рдЕрдиреБрдХреНрд░рдо рдХрд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓рд╛ рд╣реИ, рдЖрдЧреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рдХреЗрд╡рд▓ рд╕рд╛рджрдЧреА рдХреЗ рддрд╛рд░ рдХреЗ рд▓рд┐рдП рдорд╛рдирд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдмрджрд▓рд╛рд╡ рдХреЗ рдмрд┐рдирд╛ рдЙрдиреНрд╣реЗрдВ рдордирдорд╛рдирд╛ рдкрд╛рда рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдЪреАрдЬрд╝ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЖрдЬреНрдЮрд╛ рджреЗрдирд╛ рдПрдХ рдЕрдиреБрдХреНрд░рдо
x рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рддрддреНрд╡
x 1 x 2 ... x m рдФрд░ рдПрдХ рдЕрдиреБрдХреНрд░рдо
y рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рддрддреНрд╡
y 1 y 2 ... y n рд╣реЛрддрд╛ рд╣реИ ред
z ,
x рдХрд╛ рдПрдХ рдкрд░рд┐рдгрд╛рдо рд╣реИ рдпрджрд┐ рд╡рд╣рд╛рдБ рддрддреНрд╡
x рдХреЗ рдХрдбрд╝рд╛рдИ рд╕реЗ рдмрдврд╝рддреЗ рд╕реЗрдЯ рдореМрдЬреВрдж рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ
z рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
X рдФрд░
y рдХреЗ рд▓рд┐рдП
рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдХреНрд░рдо рдПрдХ рдЕрдиреБрдХреНрд░рдо
z рд╣реИ рдЬреЛ рдХрд┐
x рдФрд░
рдЙрд╕рдХреЗ рдмрд╛рдж y рдХреА рдПрдХ рдЕрдиреБрдХреНрд░рд┐рдпрд╛ рджреЛрдиреЛрдВ рд╣реИред
рдЕрдзрд┐рдХрддрдо рдХреБрд▓ рд▓рдВрдмрд╛рдИ рдЕрдзрд┐рдХрддрдо рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рд╛рде рдХреБрд▓ рдкрд░рд┐рдгрд╛рдо рд╣реИред рдкрд╛рда рдореЗрдВ рдЖрдЧреЗ рд╣рдо рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдирд╛рдо
LCS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ,
x = HA B R AHA BR ,
y = HARB OU R , рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ
LCS (x, y) = HARBR ред рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА
рдПрд▓рд╕реАрдПрд╕ рдЧрдгрдирд╛ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдкрд░ рд╕реАрдзреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдордЭрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рд╣рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реЛ рд╕рдХрддреА рд╣реИред
рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ
рдлрд╝рд╛рдЗрд▓ рддреБрд▓рдирд╛ рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдореЗрдВ рд╕рдмрд╕реЗ рдЖрдо рдЙрдкрдпреЛрдЧ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ GNU рднрд┐рдиреНрдиред рдПрд▓рд╕реАрдПрд╕ рдХреЛ рджреЛ рдЧреНрд░рдВрдереЛрдВ рдХреЗ рд▓рд┐рдП рдкрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рд╕реВрдЪреА рдХреЛ x рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╛ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рдПрдХ рддреБрдЪреНрдЫ рдХрд╛рд░реНрдп рд╣реИред рд╕рдордЧреНрд░ рдХреНрд░рдорд┐рдХрддрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рдмреЛрдирд╕ рдХреЗ рд░реВрдк рдореЗрдВ, рдЖрдк рджреЛ рдЕрдиреБрдХреНрд░рдореЛрдВ рдХреА рд╕рдорд╛рдирддрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдореАрдЯреНрд░рд┐рдХ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣реА рд╣реИ, рдЕрдм рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╡реНрдпрд╡рд╕рд╛рдп рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ рдЙрддрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдкрд╣рд▓рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдпрд╛ рд▓реЛрдХ рдХрд▓рд╛
рдХреБрдЫ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:
- рдпрджрд┐ рдЕрдиреБрдХреНрд░рдо x рдФрд░ y рдХреЗ рд▓рд┐рдП рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА LCS (x, y) = z рдХреА рдЧрдгрдирд╛ рдХреА рд╣реИ, рддреЛ рд╕рдорд╛рди рддрддреНрд╡ рдЬреЛрдбрд╝рдХрд░ x рдФрд░ y рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдЕрдиреБрдХреНрд░рдореЛрдВ рдХреЗ рд▓рд┐рдП LCS z рдФрд░ рдЗрд╕ рдЬреЛрдбрд╝реЗ рдЧрдП рддрддреНрд╡ рд╕реЗ рдорд┐рд▓рдХрд░ рдмрдиреЗрдЧрд╛
- рдпрджрд┐ рд╣рдо рдЕрдиреБрдХреНрд░рдо x рдФрд░ y рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рддрддреНрд╡ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░рд╛рдкреНрдд xa рдФрд░ yb рдХреЗ рд▓рд┐рдП, LCS рджреЛ рдореЗрдВ рд╕реЗ рдмрдбрд╝рд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП: LCS (x, yb) рдпрд╛ LCS (xa, y)
рдпреЗ рдЕрд╡рд▓реЛрдХрди рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреБрдирд░рд╛рд╡рд░реНрддрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИрдВ:
def LCS_RECURSIVE(x, y): if len(x) == 0 or len(y) == 0: return [] if x[-1] == y[-1]: return LCS_RECURSIVE(x[:-1], y[:-1]) + [x[-1]] else: left = LCS_RECURSIVE(x[:-1], y) right = LCS_RECURSIVE(x, y[:-1]) return left if len(left) > len(right) else right
рдЕрдм рдЖрдк рд╕реЛрдЪ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИред рд╕рдмрд╕реЗ рдЦрд░рд╛рдм рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЬрдм x рдФрд░ y рдХреЗ рдмреАрдЪ рд╕рдорд╛рди рд╕рдорд╛рди LCS_RECURSIVE рддрддреНрд╡ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ 2 рд▓реЗрдпрди
(x) + рд▓реЗрди (y) рдмрд╛рд░ рдХреЛ рд░рд┐рдХрд░реНрд╕рди рд▓реЗрд╡рд▓ рд▓реЗрди (x) + рд▓реЗрди (y) рдкрд░ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрдЧрд░ рдЖрдк рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдЖрдБрдЦреЗрдВ рдмрдВрдж рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдХреЛрдб:
from uuid import uuid4 x = [uuid4().hex for _ in xrange(500)] y = [uuid4().hex for _ in xrange(500)] print LCS_RECURSIVE(x,y)
рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЙрд▓ рдХреЗ рдмрд┐рдирд╛, sys.setrecursionlimit рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рд╕рдмрд╕реЗ рд╕рдлрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдирд╣реАрдВред
рдбрд╛рдпрдиреЗрдорд┐рдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдпрд╛ 64 рдХреЗрдмреА рд╕рднреА рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ
рдкреНрд░рд╢реНрди рдореЗрдВ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рдиреАрдбрд▓рдореИрди-рд╡реВрдиреНрд╢ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред
рдкреВрд░рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореИрдЯреНрд░рд┐рдХреНрд╕ рдореЗрдВ рдЪрд░рдгрдмрджреНрдз рддрд░реАрдХреЗ рд╕реЗ рдЙрдмрд▓рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдкрдВрдХреНрддрд┐рдпрд╛рдБ x рддрддреНрд╡ рд╣реИрдВ рдФрд░ рд╕реНрддрдВрдн y рддрддреНрд╡ рд╣реИрдВред рднрд░рддреЗ рд╕рдордп, рдкрд╣рд▓реЗ рд╕реЗ рдХрд┐рдП рдЧрдП рдЕрд╡рд▓реЛрдХрдиреЛрдВ рд╕реЗ рдЙрддреНрдкрдиреНрди рджреЛ рдирд┐рдпрдо рд▓рд╛рдЧреВ рд╣реЛрддреЗ рд╣реИрдВ:
1. рдпрджрд┐ рддрддреНрд╡ x
i , y
j рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ рддреЛ рд╕реЗрд▓ рдореЗрдВ (i, j) рд╕реЗрд▓ рдХрд╛ рдорд╛рди (i-1, j-1) рдПрдХ рдХреЗ рдЬреЛрдбрд╝ рдХреЗ рд╕рд╛рде рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ
2. рдпрджрд┐ рддрддреНрд╡ x
i , y
j рдХреЗ рдмрд░рд╛рдмрд░ рдирд╣реАрдВ рд╣реИ
, рддреЛ рдорд╛рдиреЛрдВ рдХреА рдЕрдзрд┐рдХрддрдо (i-1, j) рдФрд░ (i, j-1) рд╕реЗрд▓ (i, j) рдореЗрдВ рджрд░реНрдЬ рдХреА рдЬрд╛рддреА рд╣реИред
рдлрд┐рд▓рд┐рдВрдЧ рдореЗрдВ рдЖрдИ рдФрд░ рдЬреЗ рдХреЛ рдПрдХ рд╕реЗ рдмрдврд╝рдХрд░ рдПрдХ рджреЛрд╣рд░реЗ рдЪрдХреНрд░ рдореЗрдВ рдЬрдЧрд╣ рдорд┐рд▓рддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдкрд░ рдЗрд╕ рдЪрд░рдг рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╕реЗрд▓ рдорд╛рдиреЛрдВ рдХреА рдЧрдгрдирд╛ рдкрд╣рд▓реЗ рд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИ:
def fill_dyn_matrix(x, y): L = [[0]*(len(y)+1) for _ in xrange(len(x)+1)] for x_i,x_elem in enumerate(x): for y_i,y_elem in enumerate(y): if x_elem == y_elem: L[x_i][y_i] = L[x_i-1][y_i-1] + 1 else: L[x_i][y_i] = max((L[x_i][y_i-1],L[x_i-1][y_i])) return L
рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ рдЗрд╕рдХрд╛ рдЪрд┐рддреНрд░рдг:

рдХреЛрд╢рд┐рдХрд╛рдПрдБ рдЬрд┐рдирдореЗрдВ рд╕реАрдзреЗ рд╡реГрджреНрдзрд┐ рд╣реБрдИ рд╣реИ, рдкрд░ рдкреНрд░рдХрд╛рд╢ рдбрд╛рд▓рд╛ рдЧрдпрд╛ рд╣реИред рдореИрдЯреНрд░рд┐рдХреНрд╕ рдореЗрдВ рднрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЗрди рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдкрд░, рд╣рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд LCS рдорд┐рд▓рддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдкрдХреЛ рдЕрдзрд┐рдХрддрдо рд╕реЗ рдиреНрдпреВрдирддрдо рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рддрдХ рд▓реЗ рдЬрд╛рддреЗ рд╕рдордп рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдпрджрд┐ рд╕реЗрд▓ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдПрд▓рд╕реАрдПрд╕ рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рддрддреНрд╡ рдЬреЛрдбрд╝реЗрдВ, рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдКрдкрд░ рдпрд╛ рдмрд╛рдИрдВ рдУрд░ рдЖрдЧреЗ рдмрдврд╝реЗрдВ, рдЗрд╕ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдореЗрдВ рдмрдбрд╝рд╛ рдореВрд▓реНрдп рдХрд╣рд╛рдВ рд╣реИ:
def LCS_DYN(x, y): L = fill_dyn_matrix(x, y) LCS = [] x_i,y_i = len(x)-1,len(y)-1 while x_i >= 0 and y_i >= 0: if x[x_i] == y[y_i]: LCS.append(x[x_i]) x_i, y_i = x_i-1, y_i-1 elif L[x_i-1][y_i] > L[x_i][y_i-1]: x_i -= 1 else: y_i -= 1 LCS.reverse() return LCS
рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рдЬрдЯрд┐рд▓рддрд╛ рд╣реЗ (len (x) * len (y)), рд╡рд╣реА рдореЗрдореЛрд░реА рд╕реНрдХреЛрд░ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЕрдЧрд░ рдореИрдВ рд▓рд╛рдЗрди рдХреА рддреБрд▓рдирд╛ 100,000 рд▓рд╛рдЗрдиреЛрдВ рдХреА рджреЛ рдлрд╛рдЗрд▓реЛрдВ рд╕реЗ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рддреЛ рдореБрдЭреЗ рдореЗрдореЛрд░реА рдореЗрдВ 10
10 рддрддреНрд╡реЛрдВ рдХреЗ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдпрд╛рдиреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд╕реНрдореГрддрд┐Error рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдзрдордХреА рджреЗрддрд╛ рд╣реИ рдиреАрд▓реЗ рд░рдВрдЧ рд╕реЗ рд▓рдЧрднрдЧред рдЕрдЧрд▓реЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдкрд░ рдЖрдЧреЗ рдмрдврд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рддрддреНрд╡реЛрдВ x рдкрд░ рдкреНрд░рддреНрдпреЗрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдореЗрдВ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдПрд▓ рдореЗрдВ рднрд░рдиреЗ рдкрд░, рд╣рдореЗрдВ рдкрд┐рдЫрд▓реЗ рдЪрд╛рд▓ рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХреЗрд╡рд▓ рдкрдВрдХреНрддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╛рдиреА рдпрджрд┐ рдХрд╛рд░реНрдп рдХреЗрд╡рд▓ LCS рдХреА рдЧрдгрдирд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд┐рдирд╛ LCS рдХреА рд▓рдВрдмрд╛рдИ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реАрдорд┐рдд рдерд╛, рддреЛ рдпрд╣ O (len (y)) рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдЙрдкрдпреЛрдЧ рдХреЛ рдХрдо рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рдореИрдЯреНрд░рд┐рдХреНрд╕ L рдХреА рдХреЗрд╡рд▓ рджреЛ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдмрдЪрд╛рдПрдЧрд╛ред
рдПрдХ рдЬрдЧрд╣ рдпрд╛ рд╣рд┐рд░реНрд╢рдмрд░реНрдЧ рдПрд▓реНрдЧреЛрд░рд┐рдердо рдХреЗ рд▓рд┐рдП рд▓рдбрд╝рдирд╛
рдЗрд╕ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдкреАрдЫреЗ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рд╕рд░рд▓ рд╣реИ: рдпрджрд┐ рдЖрдк рдЗрдирдкреБрдЯ рдЕрдиреБрдХреНрд░рдо x = x
1 x
2 ... x
m рдХреЛ рдХрд┐рд╕реА рднреА рд╕реАрдорд╛ рд╕реВрдЪрдХрд╛рдВрдХ i рдХреЗ рд▓рд┐рдП xb = x
1 x
2 ... x
i рдФрд░ xe = x
i + 1 рд╕реЗ рджреЛ рдордирдорд╛рдиреЗ рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВ
ред x
i + 2 ... x
m , рддреЛ рдЗрд╕реА рддрд░рд╣ рд╕реЗ рд╡рд┐рднрд╛рдЬрди y рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИ (y рдореЗрдВ = y
1 y
2 ... y
j рдФрд░ ye = y
j + 1 y
j + 2 ... y
n ) рдЬреИрд╕реЗ рдХрд┐ LCS (x, y) = LCS (xb, yb) + LCS (xe, ye)ред
рдЗрд╕ рд╡рд┐рднрд╛рдЬрди рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП y рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╣реИ:
- X рдФрд░ y рдХреЗ рд▓рд┐рдП fill_dyn_matrix рдХреЗ рд╕рд╛рде рдбрд╛рдпрдирд╛рдорд┐рдХ рдореИрдЯреНрд░рд┐рдХреНрд╕ L рднрд░реЗрдВред L1 рд╣рдо рдЧрдгрдирд╛ рдХреА рдЧрдИ рдореИрдЯреНрд░рд┐рдХреНрд╕ L рдХреА рдЕрдВрддрд┐рдо рдкрдВрдХреНрддрд┐ рдХреА рдмрд░рд╛рдмрд░реА рдХрд░рддреЗ рд╣реИрдВ
- * * Xe рдФрд░ * y рдХреЗ рд▓рд┐рдП рдореИрдЯреНрд░рд┐рдХреНрд╕ L рдореЗрдВ рднрд░реЗрдВ (Pyeon рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ xe рдФрд░ y рдХреЗ рд▓рд┐рдП рд╡реНрдпреБрддреНрдХреНрд░рдо рдХреНрд░рдо): рд╕реВрдЪреА (рдЙрд▓рдЯ (x)), рд╕реВрдЪреА (рдЙрд▓рдЯ (y)))ред рд╣рдо рдЧрдгрдирд╛ рдХреА рдЧрдИ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдПрд▓ рдХреА рдЕрдВрддрд┐рдо рдкрдВрдХреНрддрд┐ рдХреЛ * L2 рдХреЗ рдмрд░рд╛рдмрд░ рдХрд░рддреЗ рд╣реИрдВ, L2 * L2 рд╕реЗ рдирджреА рд╣реИ
- рдЗрдВрдбреЗрдХреНрд╕ рдХреЗ рдмрд░рд╛рдмрд░ j рд▓реЗ рд▓реЛ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП L1 [j] + L2 [j] рдХрд╛ рдпреЛрдЧ рдЕрдзрд┐рдХрддрдо рд╣реЛ
рдЗрд╕реЗ рдореИрдЯреНрд░рд┐рдХреНрд╕ L рдХреЛ рджреЛ рд╡рд┐рдкрд░реАрдд рдЫреЛрд░реЛрдВ рд╕реЗ рднрд░рдиреЗ рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЪреВрдВрдХрд┐ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдПрд▓ рдХреА рдЕрдВрддрд┐рдо рдкрдВрдХреНрддрд┐ рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЧрдгрдирд╛ рдХреЗ рджреМрд░рд╛рди рдкреВрд░реЗ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдорд┐рд▓рдиреЗ рд╡рд╛рд▓реЗ fill_dyn_matrix рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдереЛрдбрд╝рд╛ рдмрджрд▓рд╛рд╡ рдЖрдпрд╛ рд╣реИ:
def lcs_length(x, y): curr = [0]*(1 + len(y)) for x_elem in x: prev = curr[:] for y_i, y_elem in enumerate(y): if x_elem == y_elem: curr[y_i + 1] = prev[y_i] + 1 else: curr[y_i + 1] = max(curr[y_i], prev[y_i + 1]) return curr
рдЕрдм рд╕реАрдзреЗ, рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реАред рдпрд╣ рдПрдХ рдХреНрд▓рд╛рд╕рд┐рдХ рд╡рд┐рднрд╛рдЬрди рд╣реИ рдФрд░ рдЬреАрддрддрд╛ рд╣реИ: рдЬрдмрдХрд┐ рдЕрдиреБрдХреНрд░рдо x рдореЗрдВ рддрддреНрд╡ рд╣реИрдВ, рд╣рдо x рдХреЛ рдЖрдзреЗ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, y рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╡рд┐рднрд╛рдЬрди рдкрд╛рддреЗ рд╣реИрдВ рдФрд░ рдЕрдиреБрдХреНрд░рдореЛрдВ (xb, yb) рдФрд░ (xe, ye) рдХреЗ рдЬреЛрдбрд╝реЗ рдХреЗ рд▓рд┐рдП рдкреБрдирд░рд╛рд╡рд░реНрддреА рдХреЙрд▓ рдХрд╛ рдпреЛрдЧ рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рддреБрдЪреНрдЫ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрджрд┐ x рдореЗрдВ рдПрдХ рддрддреНрд╡ рд╣реЛрддрд╛ рд╣реИ рдФрд░ y рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдмрд╕ рдЗрд╕ рдПрдХрд▓ рддрддреНрд╡ x рд╕реЗ рдПрдХ рдЕрдиреБрдХреНрд░рдо рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред
def LCS_HIRSHBERG(x, y): x_len = len(x) if x_len == 0: return [] elif x_len == 1: if x[0] in y: return [x[0]] else: return [] else: i = x_len // 2 xb, xe = x[:i], x[i:] L1 = lcs_length(xb, y) L2 = reversed(lcs_length(xe[::-1], y[::-1])) SUM = (l1 + l2 for l1,l2 in itertools.izip(L1, L2)) _, j = max((sum_val, sum_i) for sum_i, sum_val in enumerate(SUM)) yb, ye = y[:j], y[j:] return LCS_HIRSHBERG(xb, yb) + LCS_HIRSHBERG(xe, ye)
рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ O (len (y)) рдореЗрдореЛрд░реА рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рд╣реИрдВ, рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рдордп рджреЛрдЧреБрдирд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди O (len (x) len (y)) рдЕрднреА рднреА asymptotically рд╣реИред
рд╣рдВрдЯ-рд╕рд┐рдЬрдореЗрдВрд╕реНрдХреА рдПрд▓реНрдЧреЛрд░рд┐рджрдо
рдкрд╣рд▓реА рдЪреАрдЬ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдП рд╡рд╣ рд╣реИ рдорд╛рдЪрд┐рд╕ рдХреА рдореЗрдЬ рдХрд╛ рд╣реИрд╢ рдмрдирд╛рдирд╛, рдЬрд┐рд╕рдореЗрдВ рджреВрд╕рд░реЗ рдХреНрд░рдо рдХреЗ рддрддреНрд╡реЛрдВ рдХреЗ рд╕реВрдЪрдХ рд╣реЛрдВрдЧреЗред рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рдордп O (len (y)) рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдЬрдЧрд░ рдХреЛрдб рдпрд╣ рдХрд░рддрд╛ рд╣реИ:
y_matchlist = {} for index, elem in enumerate(y): indexes = y_matchlist.setdefault(elem, []) indexes.append(index) y_matchlist[elem] = indexes
HARBOR рдЕрдиреБрдХреНрд░рдо рдХреЗ рд▓рд┐рдП, рд╣реИрд╢ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реЛрдЧрд╛ {'рдП': [1], 'рдмреА': [3], 'рдПрдЪ': [0], 'рдУ': [4], 'рдЖрд░': [2, 6] , 'U': [5]}ред
рдЕрдЧрд▓рд╛, рдЕрдиреБрдХреНрд░рдо x рдХреЗ рддрддреНрд╡реЛрдВ рдХреЛ рдЫрд╛рдВрдЯрддрд╛ рд╣реИ, рддреИрдпрд╛рд░ рдХреА рдЧрдИ рд╕реВрдЪреА рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рдХреЗ рд╕рд╛рде THRESH рд╕рд░рдгреА рднрд░реЗрдВ, рддрд╛рдХрд┐ THRESH рдХреЗ k-th рддрддреНрд╡ рдХрд╛ рдорд╛рди рд╕реВрдЪрдХрд╛рдВрдХ y_index рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдмрд╢рд░реНрддреЗ рдХрд┐ THESESH [k-1] <y_index рдФрд░ y_index <THRESH [k]ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдХрд┐рд╕реА рднреА рд╕рдордп, THRESH рд╕рд░рдгреА рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд╣рдо рдЙрдкрдпреБрдХреНрдд k рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдЗрдирд░реА рдЦреЛрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред THRESH рддрддреНрд╡ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╕рдордп, рд╣рдо рдЕрдкрдиреЗ LCS рдореЗрдВ y_index рдЗрдВрдбреЗрдХреНрд╕ рдХреЗ рдЕрдиреБрд░реВрдк рдЕрдиреБрдХреНрд░рдо рддрддреНрд╡ рднреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд╕реНрдкрд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
x_length, y_length = len(x), len(y) min_length = min(x_length, y_length) THRESH = list(itertools.repeat(y_length, min_length+1)) LINK_s1 = list(itertools.repeat(None, min_length+1)) LINK_s2 = list(itertools.repeat(None, min_length+1)) THRESH[0], t = -1, 0 for x_index,x_elem in enumerate(x): y_indexes = y_matchlist.get(x_elem, []) for y_index in reversed(y_indexes): k_start = bisect.bisect_left(THRESH, y_index, 1, t) k_end = bisect.bisect_right(THRESH, y_index, k_start, t) for k in xrange(k_start, k_end+2): if THRESH[k-1] < y_index and y_index < THRESH[k]: THRESH[k] = y_index LINK_x[k] = (x_index, LINK_x[k-1]) if k > t: t = k
рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рдХреЗрд╡рд▓ LINK_x рд╕реЗ рд╣реА рдЕрдиреБрдХреНрд░рдо рдПрдХрддреНрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдЗрд╕ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рд░рдирд┐рдВрдЧ рдЯрд╛рдЗрдо O ((r + n) рд▓реЙрдЧ рдПрди) рд╣реИ, рдЬрд╣рд╛рдВ n рдмрдбрд╝реЗ рдЕрдиреБрдХреНрд░рдо рдХреА рд▓рдВрдмрд╛рдИ рд╣реИ рдФрд░ r рдореИрдЪреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реИ, рд╕рдмрд╕реЗ рдЦрд░рд╛рдм рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЬрдм r = n * n рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдкрд┐рдЫрд▓реЗ рд╕рдорд╛рдзрд╛рди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдПрдХ рдЦрд░рд╛рдм рдЪрд▓ рд░рд╣рд╛ рд╕рдордп рдорд┐рд▓рддрд╛ рд╣реИред рд╕реНрдореГрддрд┐ рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ O (r + n) рдХреЗ рдХреНрд░рдо рдХреА рд░рд╣рддреА рд╣реИрдВред
рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░
рдмрд╣реБрдд рд╕рд╛рд░реЗ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рд╣реИрдВ рдЬреЛ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддреЗ рд╣реИрдВ, asymptotically, рд╕рдмрд╕реЗ рдХреБрд╢рд▓ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо (Masek рдФрд░ Paterson) рдореЗрдВ O (n * n / log n) рд╕рдордп рдХрд╛ рдЕрдиреБрдорд╛рди рд╣реИред рдПрд▓рд╕реАрдПрд╕ рдЧрдгрдирд╛ рдореЗрдВ рд╕рдордЧреНрд░ рдЫреЛрдЯреА рджрдХреНрд╖рддрд╛ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, рдПрд▓реНрдЧреЛрд░рд┐рдердо рд░рди рд╕реЗ рдкрд╣рд▓реЗ рд╕рдмрд╕реЗ рд╕рд░рд▓ рддреИрдпрд╛рд░реА рдХреА рдЬрд╛рддреА рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ рд╢реБрд░реБрдЖрдд рдореЗрдВ рдФрд░ рдЕрдиреБрдХреНрд░рдореЛрдВ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕рдорд╛рди рддрддреНрд╡реЛрдВ рдХреЛ рдЫреЛрдбрд╝рдирд╛ рдФрд░ рдЕрдиреБрдХреНрд░рдореЛрдВ рдХреЗ рдмреАрдЪ рддреБрдЪреНрдЫ рдЕрдВрддрд░ рдХреА рдЦреЛрдЬ рдХрд░рдирд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдмрд┐рдЯ рдСрдкрд░реЗрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреБрдЫ рдЕрдиреБрдХреВрд▓рди рд╣реИрдВ рдЬреЛ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рдордп рдХреЗ рд╕реНрдкрд░реНрд╢реЛрдиреНрдореБрдЦ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред
рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рднреА рдХреЛрдб рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ