class LCS(DP): """ Counting and calculate the longest common string algorithm. The problem's description is as below. http://www.geeksforgeeks.org/dynamic-programming-set-4-longest-common-subsequence/ """ def __init__(self, str1=None, str2=None): self._suffix_matrix = SuffixMatrix(str1, str2) self._matrix = self._suffix_matrix.suffix_matrix self._str1 = str1 self._str2 = str2 self._lcs = [] def _algorithm(self): """ LCS algorithm. """ for i, s in enumerate(self._str2): for j, t in enumerate(self._str1): if t == s: self._matrix[i + 1][j + 1]['len'] = self._matrix[i][j].get('len') + 1 self._matrix[i + 1][j + 1]['direct'] = 'ul' else: self._matrix[i + 1][j + 1]['len'] = \ max(self._matrix[i + 1][j].get('len'), self._matrix[i][j + 1].get('len')) self._matrix[i + 1][j + 1]['direct'] = \ 'l' if self._matrix[i + 1][j].get('len') >= self._matrix[i][j + 1].get('len') else 'u' def _backtracking(self): """ using backtracking to find the lcs. """ def inner_backtracking(i, j): { 'ul': lambda: (inner_backtracking(i - 1, j - 1), self._lcs.append(self._str1[j - 1])), 'u': lambda: inner_backtracking(i - 1, j), 'l': lambda: inner_backtracking(i, j - 1) }.get(self._matrix[i][j]['direct'], lambda: None)() inner_backtracking(len(self._str2), len(self._str1)) def res(self): """ running the lcs algorithm and backtracking for getting the result. :return: (lcs length, lcs string) """ self._algorithm() self._backtracking() return self._matrix[len(self._str2)][len(self._str1)].get('len'), ''.join(self._lcs) def show_matrix(self): self._suffix_matrix.show_suffix()
def __init__(self, str1=None, str2=None): self._suffix_matrix = SuffixMatrix(str1, str2) self._matrix = self._suffix_matrix.suffix_matrix self._str1 = str1 self._str2 = str2 self._lcs = []