Longest Common Subsequence Algorithm
The Longest Common Subsequence (LCS) Algorithm is a dynamic programming technique used to find the length of the longest subsequence common to two sequences. A subsequence is a sequence that appears in the same order in both input sequences but not necessarily consecutively. This algorithm has a wide range of applications in various fields, such as computational biology, text comparison, and data synchronization. One notable application is in DNA sequence alignment, where the LCS algorithm helps to identify similarities between two DNA sequences by finding the longest common subsequence of base pairs.
The key idea behind the LCS algorithm is to break down the input sequences into smaller subproblems and solve them incrementally using a bottom-up approach. This is achieved by creating a two-dimensional table with dimensions equal to the lengths of the input sequences. Each cell in the table represents the length of the longest common subsequence up to that point in the input sequences. The algorithm starts by filling in the base cases (i.e., when one of the sequences has zero length) and then iterates through the table, calculating the LCS length for each cell based on its neighbors. If the current characters in both sequences match, the LCS length for that cell is one more than the value in the diagonal cell (above and to the left). If they do not match, the LCS length is the maximum of the values in the cell to the left and the cell above. Once the table is completely filled, the value in the bottom-right cell represents the length of the longest common subsequence for the two input sequences.
package DynamicProgramming;
class LongestCommonSubsequence {
public static String getLCS(String str1, String str2) {
//At least one string is null
if (str1 == null || str2 == null)
return null;
//At least one string is empty
if (str1.length() == 0 || str2.length() == 0)
return "";
String[] arr1 = str1.split("");
String[] arr2 = str2.split("");
//lcsMatrix[i][j] = LCS of first i elements of arr1 and first j characters of arr2
int[][] lcsMatrix = new int[arr1.length + 1][arr2.length + 1];
for (int i = 0; i < arr1.length + 1; i++)
lcsMatrix[i][0] = 0;
for (int j = 1; j < arr2.length + 1; j++)
lcsMatrix[0][j] = 0;
for (int i = 1; i < arr1.length + 1; i++) {
for (int j = 1; j < arr2.length + 1; j++) {
if (arr1[i - 1].equals(arr2[j - 1])) {
lcsMatrix[i][j] = lcsMatrix[i - 1][j - 1] + 1;
} else {
lcsMatrix[i][j] = lcsMatrix[i - 1][j] > lcsMatrix[i][j - 1] ? lcsMatrix[i - 1][j] : lcsMatrix[i][j - 1];
}
}
}
return lcsString(str1, str2, lcsMatrix);
}
public static String lcsString(String str1, String str2, int[][] lcsMatrix) {
StringBuilder lcs = new StringBuilder();
int i = str1.length(),
j = str2.length();
while (i > 0 && j > 0) {
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
lcs.append(str1.charAt(i - 1));
i--;
j--;
} else if (lcsMatrix[i - 1][j] > lcsMatrix[i][j - 1]) {
i--;
} else {
j--;
}
}
return lcs.reverse().toString();
}
public static void main(String[] args) {
String str1 = "DSGSHSRGSRHTRD";
String str2 = "DATRGAGTSHS";
String lcs = getLCS(str1, str2);
//Print LCS
if (lcs != null) {
System.out.println("String 1: " + str1);
System.out.println("String 2: " + str2);
System.out.println("LCS: " + lcs);
System.out.println("LCS length: " + lcs.length());
}
}
}