Created
September 29, 2013 17:21
-
-
Save Kraks/6754510 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| # find an LCS (Longest Common Subsequence). | |
| # *public domain* | |
| def find_lcs_len(s1, s2): | |
| m = [ [ 0 for x in s2 ] for y in s1 ] | |
| for p1 in range(len(s1)): | |
| for p2 in range(len(s2)): | |
| if s1[p1] == s2[p2]: | |
| if p1 == 0 or p2 == 0: | |
| m[p1][p2] = 1 | |
| else: | |
| m[p1][p2] = m[p1-1][p2-1]+1 | |
| elif m[p1-1][p2] < m[p1][p2-1]: | |
| m[p1][p2] = m[p1][p2-1] | |
| else: # m[p1][p2-1] < m[p1-1][p2] | |
| m[p1][p2] = m[p1-1][p2] | |
| return m[-1][-1] | |
| def find_lcs(s1, s2): | |
| # length table: every element is set to zero. | |
| m = [ [ 0 for x in s2 ] for y in s1 ] | |
| # direction table: 1st bit for p1, 2nd bit for p2. | |
| d = [ [ None for x in s2 ] for y in s1 ] | |
| # we don't have to care about the boundery check. | |
| # a negative index always gives an intact zero. | |
| for p1 in range(len(s1)): | |
| for p2 in range(len(s2)): | |
| if s1[p1] == s2[p2]: | |
| if p1 == 0 or p2 == 0: | |
| m[p1][p2] = 1 | |
| else: | |
| m[p1][p2] = m[p1-1][p2-1]+1 | |
| d[p1][p2] = 3 # 11: decr. p1 and p2 | |
| elif m[p1-1][p2] < m[p1][p2-1]: | |
| m[p1][p2] = m[p1][p2-1] | |
| d[p1][p2] = 2 # 10: decr. p2 only | |
| else: # m[p1][p2-1] < m[p1-1][p2] | |
| m[p1][p2] = m[p1-1][p2] | |
| d[p1][p2] = 1 # 01: decr. p1 only | |
| (p1, p2) = (len(s1)-1, len(s2)-1) | |
| # now we traverse the table in reverse order. | |
| s = [] | |
| while 1: | |
| print p1,p2 | |
| c = d[p1][p2] | |
| if c == 3: s.append(s1[p1]) | |
| if not ((p1 or p2) and m[p1][p2]): break | |
| if c & 2: p2 -= 1 | |
| if c & 1: p1 -= 1 | |
| s.reverse() | |
| return ''.join(s) | |
| if __name__ == '__main__': | |
| print find_lcs('abcoisjf','axbaoeijf') | |
| print find_lcs_len('abcoisjf','axbaoeijf') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment