Class LongestCommonSubsequence

  • All Implemented Interfaces:
    SimilarityScore<java.lang.Integer>

    public class LongestCommonSubsequence
    extends java.lang.Object
    implements SimilarityScore<java.lang.Integer>
    A similarity algorithm indicating the length of the longest common subsequence between two strings.

    The Longest common subsequence algorithm returns the length of the longest subsequence that two strings have in common. Two strings that are entirely different, return a value of 0, and two strings that return a value of the commonly shared length implies that the strings are completely the same in value and position. Note. Generally this algorithm is fairly inefficient, as for length m, n of the input CharSequence's left and right respectively, the runtime of the algorithm is O(m*n).

    As of version 1.10, a more space-efficient of the algorithm is implemented. The new algorithm has linear space complexity instead of quadratic. However, time complexity is still quadratic in the size of input strings.

    The implementation is based on Hirschberg's Longest Commons Substring algorithm (cited below).

    For further reading see:

    • Lothaire, M. Applied combinatorics on words. New York: Cambridge U Press, 2005. 12-13
    • D. S. Hirschberg, "A linear space algorithm for computing maximal common subsequences," CACM, 1975, pp. 341--343.
    Since:
    1.0
    • Method Summary

      All Methods Instance Methods Concrete Methods Deprecated Methods 
      Modifier and Type Method Description
      java.lang.Integer apply​(java.lang.CharSequence left, java.lang.CharSequence right)
      Calculates the longest common subsequence similarity score of two CharSequence's passed as input.
      java.lang.CharSequence logestCommonSubsequence​(java.lang.CharSequence left, java.lang.CharSequence right)
      Deprecated.
      Deprecated as of 1.2 due to a typo in the method name.
      java.lang.CharSequence longestCommonSubsequence​(java.lang.CharSequence left, java.lang.CharSequence right)
      Computes the longest common subsequence between the two CharSequence's passed as input.
      int[][] longestCommonSubstringLengthArray​(java.lang.CharSequence left, java.lang.CharSequence right)
      Deprecated.
      Deprecated as of 1.10.
      • Methods inherited from class java.lang.Object

        equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • LongestCommonSubsequence

        public LongestCommonSubsequence()
    • Method Detail

      • apply

        public java.lang.Integer apply​(java.lang.CharSequence left,
                                       java.lang.CharSequence right)
        Calculates the longest common subsequence similarity score of two CharSequence's passed as input.

        This method implements a more efficient version of LCS algorithm which has quadratic time and linear space complexity.

        This method is based on newly implemented algorithmB(CharSequence, CharSequence). An evaluation using JMH revealed that this method is almost two times faster than its previous version.

        Specified by:
        apply in interface SimilarityScore<java.lang.Integer>
        Parameters:
        left - first character sequence
        right - second character sequence
        Returns:
        length of the longest common subsequence of left and right
        Throws:
        java.lang.IllegalArgumentException - if either String input null
      • logestCommonSubsequence

        @Deprecated
        public java.lang.CharSequence logestCommonSubsequence​(java.lang.CharSequence left,
                                                              java.lang.CharSequence right)
        Deprecated.
        Deprecated as of 1.2 due to a typo in the method name. Use longestCommonSubsequence(CharSequence, CharSequence) instead. This method will be removed in 2.0.
        Computes the longest common subsequence between the two CharSequence's passed as input.

        Note, a substring and subsequence are not necessarily the same thing. Indeed, abcxyzqrs and xyzghfm have both the same common substring and subsequence, namely xyz. However, axbyczqrs and abcxyzqtv have the longest common subsequence xyzq because a subsequence need not have adjacent characters.

        For reference, we give the definition of a subsequence for the reader: a subsequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements.

        Parameters:
        left - first character sequence
        right - second character sequence
        Returns:
        the longest common subsequence found
        Throws:
        java.lang.IllegalArgumentException - if either String input null
      • longestCommonSubsequence

        public java.lang.CharSequence longestCommonSubsequence​(java.lang.CharSequence left,
                                                               java.lang.CharSequence right)
        Computes the longest common subsequence between the two CharSequence's passed as input.

        This method implements a more efficient version of LCS algorithm which although has quadratic time, it has linear space complexity.

        Note, a substring and subsequence are not necessarily the same thing. Indeed, abcxyzqrs and xyzghfm have both the same common substring and subsequence, namely xyz. However, axbyczqrs and abcxyzqtv have the longest common subsequence xyzq because a subsequence need not have adjacent characters.

        For reference, we give the definition of a subsequence for the reader: a subsequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements.

        Parameters:
        left - first character sequence
        right - second character sequence
        Returns:
        the longest common subsequence found
        Throws:
        java.lang.IllegalArgumentException - if either String input null
        Since:
        1.2
      • longestCommonSubstringLengthArray

        @Deprecated
        public int[][] longestCommonSubstringLengthArray​(java.lang.CharSequence left,
                                                         java.lang.CharSequence right)
        Deprecated.
        Deprecated as of 1.10. A more efficient implementation for calculating LCS is now available. Use longestCommonSubsequence(CharSequence, CharSequence) instead to directly calculate the LCS. This method will be removed in 2.0.
        Computes the lcsLengthArray for the sake of doing the actual lcs calculation. This is the dynamic programming portion of the algorithm, and is the reason for the runtime complexity being O(m*n), where m=left.length() and n=right.length().
        Parameters:
        left - first character sequence
        right - second character sequence
        Returns:
        lcsLengthArray