# Ticket #14969: trac_14969.patch

File trac_14969.patch, 3.0 KB (added by ncohen, 7 years ago)
• ## sage/combinat/words/finite_word.py

```# HG changeset patch
# User Nathann Cohen <nathann.cohen@gmail.com>
# Date 1374746827 -7200
#      Thu Jul 25 12:07:07 2013 +0200
# Node ID 1bbb2f6416b3b032144ab1038a34b5396e106a27
# Parent  4de3b579bf03a8f2c009d2e5e9e0768151d67823
Longest Common subword

diff --git a/sage/combinat/words/finite_word.py b/sage/combinat/words/finite_word.py```
 a possible = xrange(1, n) return filter(self.has_period, possible) def longest_common_subword(self,other): r""" Returns a longest subword of ``self`` and ``other``. For more information, see :wikipedia:`Longest_common_subsequence_problem`. INPUT: - ``other`` -- a word ALGORITHM: For any indices `i,j'`, we compute the longest common subword ``lcs[i,j]`` of `self[:i]` and `other[:j]`. This can be easily obtained as the maximum of - ``lcs[i-1,j]`` - ``lcs[i,j-1]`` - ``lcs[i-1,j-1]+1`` if ``self[i]==other[j]`` EXAMPLE:: sage: w1 = Word("1010101010101010101010101010101010101010") sage: w2 = Word("0011001100110011001100110011001100110011") sage: w1.longest_common_subword(w2) word: 00110011001100110011010101010 TESTS:: sage: Word().longest_common_subword(Word()) word: .. SEEALSO:: :meth:`is_subword_of` """ from sage.combinat.words.word import Word if len(self) == 0 or len(other) == 0: return Word() w2 = list(other) # In order to avoid storing lcs[i,j] for each pair i,j of indices, we # only store the lcs[i,j] for two consecutive values of i. At any step # of the algorithm, lcs[i,j] is stored at lcs[0][j] and lcs[-1,j] is # stored at lcs[1][j] l1 = self[0] # The weird +1 that follows exists to make sure that lcs[i,-1] returns # the empty word lcs = [[[] for i in range(len(w2)+1)] for j in range(2)] for i,l1 in enumerate(self): for j,l2 in enumerate(other): lcs[0][j] = max(lcs[0][j-1],lcs[1][j],lcs[1][j-1] + ([l1] if l1==l2 else []),key=len) # Maintaining the meaning of lcs for the next loop lcs.pop(1) lcs.insert(0,[[] for i in range(len(w2)+1)]) return Word(lcs[1][-2]) def is_subword_of(self, other): r""" Returns True is self is a subword of other, and False otherwise. EXAMPLES:: sage: Word().is_subword_of(Word('123')) True sage: Word('321').is_subword_of(Word('11122212112122133111222332')) False .. SEEALSO:: :meth:`longest_common_subword` """ its = iter(self) try: