/** * @author San Skulrattanakulchai and Karl Knight * * Computes the longest common subsequence (LCS) of two strings. * * This program reads two lines from standard input, treating each line as * a string of characters. It then computes their LCS and prints both strings * and the LCS. Here are some sample runs. * * % java LCS < example1.txt * X: m a r c h * Y: a p r i l * LCS(X, Y): a r * * % java LCS < example2.txt * X: d y n a m i c p r o g r a m m i n g * Y: d i v i d e a n d c o n q u e r * LCS(X, Y): d i c o n * * % java LCS < example3.txt * X: s a i n t * Y: s a t a n * LCS(X, Y): s a t */ public class LCS { /* * @param X a non-null String * @param Y a non-null String * @return The optimizing table with values defined by the LCS recurrence */ private static int[][] optimizingTable(String X, String Y) { int m = X.length(); int n = Y.length(); int[][] opt = new int[m+1][n+1]; for (int j = 0; j <= n; j++) opt[m][j] = 0; for (int i = 0; i <= m; i++) opt[i][n] = 0; for (int i = m-1; i >= 0; i--) { for (int j = n-1; j >= 0; j--) { if (X.charAt(i) == Y.charAt(j)) { opt[i][j] = opt[i+1][j+1] + 1; } else { opt[i][j] = Math.max(opt[i][j+1], opt[i+1][j]); } } } return opt; } /** * @param X a non-null String * @param Y a non-null String * @return a string which is a longest common subsequence (LCS) of X and Y */ private static String lcs(String X, String Y) { int[][] opt = optimizingTable(X, Y); int m = X.length(); int n = Y.length(); int i = 0; int j = 0; StringBuilder sb = new StringBuilder(); while ((i < m) && (j < n)) { if (X.charAt(i) == Y.charAt(j)) { sb.append(X.charAt(i)); i++; j++; } else if (opt[i+1][j] > opt[i][j+1]) { i++; } else { /* (opt[i+1][j] <= opt[i][j+1]) */ j++; } } return sb.toString(); } /** * @param string a non-null String * @return a new String with the chars in string interspersed with blank chars */ private static String explode(String string) { StringBuilder sb = new StringBuilder(); if (string.length() > 0) { sb.append(string.charAt(0)); for (int i = 1; i < string.length(); i++) { sb.append(' '); sb.append(string.charAt(i)); } } return sb.toString(); } public static void main(String[] args) { String X = StdIn.readLine(); String Y = StdIn.readLine(); System.out.println("X: " + explode(X)); System.out.println("Y: " + explode(Y)); System.out.println("LCS(X, Y): " + explode(lcs(X, Y))); } }